source: extensions/EStat/lib/statDBMonth.class.inc.php @ 17758

Last change on this file since 17758 was 17758, checked in by grum, 12 years ago

version 0.1.0b

. Fix install bugs
. Manage anonymous directories
. Manage CSV export options settings
. Fix IPadress<=>country association bug & improve join performances
. Fix bug on IP filter
. Improve performances for history consult

  • Property svn:executable set to *
File size: 47.6 KB
Line 
1<?php
2
3require_once('statDB.class.inc.php');
4
5/**
6 * specific class for SQLite monthly stat managment
7 */
8class StatDBMonth extends StatDB
9{
10  protected $year='';
11  protected $month='';
12  protected $nbDaysMonth=0;
13
14  /**
15   * constructor
16   *
17   * @param String $directory: directory where the sqlite file is saved
18   * @param String $fileName: file name (without extension)
19   */
20  public function __construct($directory='', $fileName='', $year='', $month='')
21  {
22    parent::__construct($directory, $fileName);
23    $this->setPeriod($year, $month);
24  }
25
26
27  /**
28   * define the covered period (year/month)
29   * @param String $year;
30   * @param String $month;
31   * @return String
32   */
33  public function setPeriod($year, $month)
34  {
35    $this->month=$month;
36    $this->year=$year;
37    $this->fileRootName=ASDF_FILE_ROOT_MONTH.$year.$month;
38
39    $this->nbDaysMonth=date('d', strtotime('-1 day', strtotime('+1 month', strtotime("$year-$month-01"))))*1;
40
41    return($this->fileRootName);
42  }
43
44
45  /**
46   * return the number of days for the month
47   *
48   * @return Integer
49   */
50  public function getNbDays()
51  {
52    return($this->nbDaysMonth);
53  }
54
55  /**
56   * add a log record
57   *
58   * Data have to be provided as an array with keys:
59   *      array(
60   *         'date'             => integer
61   *         'IPadress'         => string
62   *         'userId'           => integer
63   *         'catId'            => integer
64   *         'imageId'          => integer
65   *         'tagsId'           => string
66   *         'section'          => string
67   *         'userAgent'        => string
68   *         'uaBrowser'        => integer
69   *         'uaBrowserVersion' => integer
70   *         'uaEngine'         => integer
71   *         'uaEngineVersion'  => integer
72   *         'uaOS'             => integer
73   *         'uaOSVersion'      => integer
74   *         'uaType'           => integer
75   *         'screenSizeW'      => integer
76   *         'screenSizeH'      => integer
77   *      )
78   *
79   * missing values are set to default value
80   * country is defined automatically after buildIPCountry call; set to '' while
81   * call is not made
82   *
83   * @param Array $log : a record
84   * @return String : true if log was added, otherwise false
85   */
86  public function addLog($value)
87  {
88    if(is_array($value) and $this->dbHandle!=null)
89    {
90      // set default values if needed
91      if(!isset($value['date'])) $value['date']=time();
92      if(!isset($value['IPadress'])) $value['IPadress']='0.0.0.0';
93      if(!isset($value['userId'])) $value['userId']=0;
94      if(!isset($value['catId'])) $value['catId']=0;
95      if(!isset($value['imageId'])) $value['imageId']=0;
96      if(!isset($value['section'])) $value['section']='';
97      if(!isset($value['tagsId'])) $value['tagsId']='';
98      if(!isset($value['userAgent'])) $value['userAgent']='';
99      if(!isset($value['uaBrowser'])) $value['uaBrowser']=0;
100      if(!isset($value['uaBrowserVersion'])) $value['uaBrowserVersion']='';
101      if(!isset($value['uaEngine'])) $value['uaEngine']=0;
102      if(!isset($value['uaEngineVersion'])) $value['uaEngineVersion']='';
103      if(!isset($value['uaOS'])) $value['uaOS']=0;
104      if(!isset($value['uaOSVersion'])) $value['uaOSVersion']='';
105      if(!isset($value['uaType'])) $value['uaType']=0;
106      if(!isset($value['screenSizeW'])) $value['screenSizeW']=0;
107      if(!isset($value['screenSizeH'])) $value['screenSizeH']=0;
108
109      $value['IPadress']=self::IPBinaryEncode($value['IPadress']);
110
111      // insert log
112      $sql="INSERT INTO logs
113            (date, IPadress, country, userId, catId, imageId, tagsId, section,
114             userAgent, uaBrowser, uaBrowserVersion, uaEngine, uaEngineVersion,
115             uaOS, uaOSVersion, uaType, screenSizeW, screenSizeH)
116            VALUES (".$value['date'].", ".
117                      //"'".$this->dbHandle->escapeString($value['IPadress'])."', ".
118                      ":IP, ".
119                      "'', ".
120                      $value['userId'].", ".
121                      $value['catId'].", ".
122                      $value['imageId'].", ".
123                      "'".$value['tagsId']."', ".
124                      "'".$value['section']."', ".
125                      "'".$this->dbHandle->escapeString($value['userAgent'])."', ".
126                      $value['uaBrowser'].", ".
127                      "'".$value['uaBrowserVersion']."', ".
128                      $value['uaEngine'].", ".
129                      "'".$value['uaEngineVersion']."', ".
130                      $value['uaOS'].", ".
131                      "'".$value['uaOSVersion']."', ".
132                      $value['uaType'].", ".
133                      $value['screenSizeW'].", ".
134                      $value['screenSizeH']." );";
135//echo "$sql\n";
136      $sqlStm=$this->dbHandle->prepare($sql);
137      $sqlStm->bindValue(':IP', $value['IPadress'], SQLITE3_BLOB);
138      return($sqlStm->execute());
139    }
140    return(false);
141  }
142
143  /**
144   * return detailled logs
145   *
146   * $page: the page number asked; first page is 1=>lower value means to get all values
147   * $nbItemsPage: the number of items returned per; 0 means no limit
148   *
149   *
150   * in ASDF_GET_ROWS mode, each returned logs is an array:
151   *      array(
152   *         'date'             => integer
153   *         'IPadress'         => string
154   *         'userId'           => integer
155   *         'catId'            => integer
156   *         'imageId'          => integer
157   *         'tagsId'           => string
158   *         'section'          => string
159   *         'userAgent'        => string
160   *         'uaBrowser'        => integer
161   *         'uaBrowserVersion' => integer
162   *         'uaEngine'         => integer
163   *         'uaEngineVersion'  => integer
164   *         'uaOS'             => integer
165   *         'uaOSVersion'      => integer
166   *         'uaType'           => integer
167   *         'screenSizeW'      => integer
168   *         'screenSizeH'      => integer
169   *      )
170   *
171   * for each filtered item, are given an array:
172   *  array(
173   *   'operator' => '',
174   *   'value' => '',
175   *   'minValue' => '',
176   *   'maxValue' =>
177   *  )
178   *
179   * operator can take the following values:
180   *    '=', '>', '<', '>=', '<=', '!='
181   *        in this case, the index 'value' have to be set
182   *
183   *    'in'
184   *        in this case, the index 'value' have to be an array of needed value
185   *
186   *    'between'
187   *        in this case, the indexes 'minValue' and 'maxValue' have to be set
188   *
189   *
190   * filterable items are
191   *  'date'       (string) 'YYYY-MM-DD HH:II:SS' : '=', '>', '<', '>=', '<=', '!=', 'between'
192   *  'IPadress'   (string) 'xxx.xxx.xxx.xxx'     : '=', '!=', 'in', 'between'
193   *  'section'    (string)                       : '=', '!=', 'in'
194   *  'tagsId'     (integer)                      : '=', '!=', 'in'
195   *  'userId'     (integer)                      : '=', '!=', 'in'
196   *  'catId'      (integer)                      : '=', '!=', 'in'
197   *  'imageId'    (integer)                      : '=', '!=', 'in'
198   *  'uaBrowser'  (integer)                      : '=', '!=', 'in'
199   *  'uaEngine'   (integer)                      : '=', '!=', 'in'
200   *  'uaOS'       (integer)                      : '=', '!=', 'in'
201   *  'uaType'     (integer)                      : '=', '!=', 'in'
202   *  => version are not filterable, it's normal, it's not implemented :)
203   *     May be one day, if it's really interesting do to it...
204   *
205   * $order is an array allowing to set how data are sorted; column priority is set by
206   * the order of items in the array
207   * Each item of the array is an array with the following properties:
208   * Array(
209   *  'id'        => string (columnId)
210   *  'direction' => string ('A' for Asc, 'D' for Desc)
211   * )
212   *
213   * In the following example:
214   *  $order=Array(
215   *     Array('id' => 'uaBrowser', 'direction' => 'D'),
216   *     Array('id' => 'uaOS', 'direction' => 'A')
217   *  )
218   * the 'order by' clause will be: ORDER BY uaBrowser ASC, uaOS DESC
219   * => as for filter, version are not sortable
220   *
221   *
222   * @param Integer $mode: type of result needed
223   *                          . ASDF_GET_ROWS return an array of logs
224   *                          . ASDF_GET_COUNT return the number of logs
225   * @param Integer $page: page number
226   * @param Integer $nbItemsPage: number of items per page
227   * @param Array $filter : filters to apply
228   * @param Array $order: sort to apply
229   * @return
230   */
231  public function getLogs($mode=ASDF_GET_ROWS, $page=0, $nbItemsPage=0, $filter=array(), $order=array())
232  {
233    switch($mode)
234    {
235      case ASDF_GET_COUNT:
236        $returned=0;
237        break;
238      case ASDF_GET_ROWS:
239        $returned=array();
240        break;
241    }
242    if($this->dbHandle==null) return($returned);
243
244    // initialize filter
245    if(!is_array($filter)) $filter=array();
246
247    if(!isset($filter['date'])) $filter['date']=null;
248    if(!isset($filter['IPadress'])) $filter['IPadress']=null;
249    if(!isset($filter['section'])) $filter['section']=null;
250    if(!isset($filter['tagsId'])) $filter['tagsId']=null;
251    if(!isset($filter['userId'])) $filter['userId']=null;
252    if(!isset($filter['catId'])) $filter['catId']=null;
253    if(!isset($filter['imageId'])) $filter['imageId']=null;
254    if(!isset($filter['uaBrowser'])) $filter['uaBrowser']=null;
255    if(!isset($filter['uaEngine'])) $filter['uaEngine']=null;
256    if(!isset($filter['uaOS'])) $filter['uaOS']=null;
257    if(!isset($filter['uaType'])) $filter['uaType']=null;
258
259    $filter['IPadress']=$this->checkIPFilter($filter['IPadress']);
260    // check filter values - getOperator check and 'clean' the filter
261    $filter['date']=$this->getOperator($filter['date'], 'date');
262    $filter['IPadress']=$this->getOperator($filter['IPadress'], 'IP');
263    $filter['section']=$this->getOperator($filter['section'], 'string');
264    $filter['tagsId']=$this->getOperator($filter['tagsId'], 'integer');
265    $filter['userId']=$this->getOperator($filter['userId'], 'integer');
266    $filter['catId']=$this->getOperator($filter['catId'], 'integer');
267    $filter['imageId']=$this->getOperator($filter['imageId'], 'integer');
268    $filter['uaBrowser']=$this->getOperator($filter['uaBrowser'], 'integer');
269    $filter['uaEngine']=$this->getOperator($filter['uaEngine'], 'integer');
270    $filter['uaOS']=$this->getOperator($filter['uaOS'], 'integer');
271    $filter['uaType']=$this->getOperator($filter['uaType'], 'integer');
272
273    // initialize order
274    $orderBy=array();
275    if(!is_array($order)) $order=array();
276    foreach($order as $sort)
277    {
278      if(isset($sort['id']) and isset($sort['direction']))
279      {
280        if(($sort['id']=='date' or
281            $sort['id']=='IPadress' or
282            $sort['id']=='section' or
283            $sort['id']=='tagsId' or
284            $sort['id']=='userId' or
285            $sort['id']=='catId' or
286            $sort['id']=='imageId' or
287            $sort['id']=='uaBrowser' or
288            $sort['id']=='uaEngine' or
289            $sort['id']=='uaOS' or
290            $sort['id']=='uaType') and
291           ($sort['direction']=='A' or
292            $sort['direction']=='D')
293          ) $orderBy[]=$sort;
294      }
295    }
296    // set default order if nothing available is provided
297    if(count($orderBy)==0)
298      $orderBy=array(
299        array('id'=>'date', 'direction'=>'D'),
300        array('id'=>'id', 'direction'=>'A')
301      );
302    // to optimize query, if date is the first field selected for order by,
303    // all other fields are removed; exception: if IPadress is the second one this
304    // field is kept
305    $tmp=$orderBy;
306    if($tmp[0]['id']=='date')
307    {
308      $orderBy=array($tmp[0]);
309      if($tmp[1]['id']=='IPadress')
310      {
311        $orderBy[]=$tmp[1];
312      }
313    }
314
315    //build ORDER BY clause
316    $orderBy=$this->buildOrderByClause($orderBy);
317
318    //build WHERE clause
319    $IPList=array();
320    $where=$this->buildWhereClause($filter,$IPList);
321
322    // build LIMIT clause
323    $limit=$this->buildLimitClause($page, $nbItemsPage);
324
325    // execute request
326    switch($mode)
327    {
328      case ASDF_GET_ROWS:
329          $sql="SELECT id, date, IPadress, country, userId, catId, imageId, tagsId, section,
330                       userAgent, uaBrowser, uaBrowserVersion, uaEngine, uaEngineVersion,
331                       uaOS, uaOSVersion, uaType, screenSizeW, screenSizeH
332                FROM logs $where $orderBy $limit;";
333
334          $sqlStm=$this->dbHandle->prepare($sql);
335          foreach($IPList as $num=>$IP)
336          {
337            $sqlStm->bindValue(':IP'.$num, $IP, SQLITE3_BLOB);
338          }
339
340          $result=$sqlStm->execute();
341          if($result)
342          {
343            while($row=$result->fetchArray(SQLITE3_ASSOC))
344            {
345              $row['IPadress']=self::IPBinaryDecode($row['IPadress']);
346              $returned[]=$row;
347            }
348          }
349        break;
350      case ASDF_GET_COUNT:
351          $sql="SELECT COUNT(id) AS nb
352                FROM logs $where;";
353
354          $sqlStm=$this->dbHandle->prepare($sql);
355          foreach($IPList as $num=>$IP)
356          {
357            $sqlStm->bindValue(':IP'.$num, $IP, SQLITE3_BLOB);
358          }
359
360          $result=$sqlStm->execute();
361          if($result)
362          {
363            while($row=$result->fetchArray(SQLITE3_ASSOC))
364            {
365              $returned=$row['nb'];
366            }
367          }
368        break;
369    }
370    return($returned);
371  }
372
373
374
375  /**
376   * returns stats from useragent strings (os, browser, engine, type)
377   *
378   * $page: the page number asked; first page is 1=>lower value means to get all values
379   * $nbItemsPage: the number of items returned per; 0 means no limit
380   *
381   *
382   * in ASDF_GET_ROWS mode, each returned logs is an array of asked fields
383   * at least, the following fields are always returned:
384   *  'nbVisits' => number of visits
385   *  'uaValue'  => value (meaning of this information can change)
386   *
387   *
388   * all fields are filterable, except 'nbVisits' that can't be filtered
389   *
390   * available fields values are:
391   *   'uaData'    => return the type of data; can get one of the following values
392   *                          UA_DATA_BROWSER: stat about browser
393   *                          UA_DATA_ENGINE: stat about engine
394   *                          UA_DATA_OS: stat about OS
395   *                          UA_DATA_BROWSER_TYPE: stat about browser type
396   *   'day'       => return detailled stat per day
397   *   'uaVersion' => return detailled stat per version (browser version, os version, ...)
398   *
399   * @param Integer $mode: type of result needed
400   *                          . ASDF_GET_ROWS return an array of logs
401   *                          . ASDF_GET_COUNT return the number of logs
402   * @param Integer $page: page number
403   * @param Integer $nbItemsPage: number of items per page
404   * @param Array $fields : additional fields to be returned
405   * @param Array $filter : filters to apply => see getLogs function for usage
406   * @param Array $order: sort to apply      => see getLogs function for usage; all fields can be sorted
407   * @return
408   */
409  public function getStatUserAgent($mode=ASDF_GET_ROWS, $page=0, $nbItemsPage=0, $fields=array(), $filter=array(), $order=array())
410  {
411    switch($mode)
412    {
413      case ASDF_GET_COUNT:
414        $returned=0;
415        break;
416      case ASDF_GET_ROWS:
417        $returned=array();
418        break;
419    }
420    if($this->dbHandle==null) return($returned);
421
422    $select=array('uaData', 'SUM(visits) AS nbVisits');
423    $groupBy=array('uaData');
424    // initialize fields list
425    foreach($fields as $field)
426    {
427      if($field=='uaValue' or
428         $field=='day' or
429         $field=='uaVersion')
430      {
431        $select[]=$field;
432        $groupBy[]=$field;
433      }
434    }
435
436    // initialize filter
437    if(!is_array($filter)) $filter=array();
438
439    if(!isset($filter['uaData'])) $filter['uaData']=null;
440    if(!isset($filter['uaValue'])) $filter['uaValue']=null;
441    if(!isset($filter['day'])) $filter['day']=null;
442    if(!isset($filter['uaVersion'])) $filter['uaVersion']=null;
443
444    // check filter values - getOperator check and 'clean' the filter
445    $filter['uaData']=$this->getOperator($filter['uaData'], 'integer');
446    $filter['uaValue']=$this->getOperator($filter['uaValue'], 'integer');
447    $filter['day']=$this->getOperator($filter['day'], 'integer');
448    $filter['uaVersion']=$this->getOperator($filter['uaVersion'], 'string');
449
450
451    // initialize order
452    $orderBy=array();
453    if(!is_array($order)) $order=array();
454    foreach($order as $sort)
455    {
456      if(isset($sort['id']) and isset($sort['direction']))
457      {
458        if((($sort['id']=='uaData' or
459             $sort['id']=='day' or
460             $sort['id']=='uaVersion' or
461             $sort['id']=='uaValue' ) and
462            in_array($sort['id'], $select) or
463             $sort['id']=='nbVisits') and
464           ($sort['direction']=='A' or
465            $sort['direction']=='D')
466          ) $orderBy[]=$sort;
467      }
468    }
469    // set default order if nothing available is provided
470    if(count($orderBy)==0)
471    {
472      if(in_array('day', $select))
473        $orderBy[]=array('id'=>'day', 'direction'=>'A');
474      $orderBy[]=array('id'=>'nbVisits', 'direction'=>'D');
475    }
476
477    // build SELECT & GROUP By clauses
478    $select="SELECT ".implode(',', $select);
479    $groupBy=(count($groupBy)>0)?" GROUP BY ".implode(',', $groupBy):'';
480
481    //build ORDER BY clause
482    $orderBy=$this->buildOrderByClause($orderBy);
483
484    //build WHERE clause
485    $IPList=array();
486    $where=$this->buildWhereClause($filter, $IPList);
487
488    // build LIMIT clause
489    $limit=$this->buildLimitClause($page, $nbItemsPage);
490
491    // execute request
492    switch($mode)
493    {
494      case ASDF_GET_ROWS:
495          $sql=$select." FROM statua ".$where.$groupBy.$orderBy.$limit;
496
497          $sqlStm=$this->dbHandle->prepare($sql);
498
499          $result=$sqlStm->execute();
500          if($result)
501          {
502            while($row=$result->fetchArray(SQLITE3_ASSOC))
503            {
504              $returned[]=$row;
505            }
506          }
507        break;
508      case ASDF_GET_COUNT:
509          $sql="SELECT COUNT(*) AS nb
510                FROM statua $where;";
511
512          $sqlStm=$this->dbHandle->prepare($sql);
513
514          $result=$sqlStm->execute();
515          if($result)
516          {
517            while($row=$result->fetchArray(SQLITE3_ASSOC))
518            {
519              $returned=$row['nb'];
520            }
521          }
522        break;
523    }
524    return($returned);
525  }
526
527
528  /**
529   * returns stats from IP
530   *
531   * $page: the page number asked; first page is 1=>lower value means to get all values
532   * $nbItemsPage: the number of items returned per; 0 means no limit
533   *
534   *
535   * in ASDF_GET_ROWS mode, each returned logs is an array of asked fields
536   * at least, the following fields are always returned:
537   *  'nbVisits' => number of visits
538   *
539   * all fields are filterable, except 'nbVisits' that can't be filtered
540   *
541   * available fields values are:
542   *   'IPadress' => return the IP address
543   *   'day'      => return detailled stat per day
544   *   'uaType'   => return detailled stat per browser type
545   *   'country'  => return detailled stat per country
546   *   'catId'    => return detailled stat per category
547   *
548   * @param Integer $mode: type of result needed
549   *                          . ASDF_GET_ROWS return an array of logs
550   *                          . ASDF_GET_COUNT return the number of logs
551   * @param Integer $page: page number
552   * @param Integer $nbItemsPage: number of items per page
553   * @param Array $fields : additional fields to be returned
554   * @param Array $filter : filters to apply => see getLogs function for usage
555   * @param Array $order: sort to apply      => see getLogs function for usage; all fields can be sorted
556   * @return
557   */
558  public function getStatIP($mode=ASDF_GET_ROWS, $page=0, $nbItemsPage=0, $fields=array(), $filter=array(), $order=array())
559  {
560    switch($mode)
561    {
562      case ASDF_GET_COUNT:
563        $returned=0;
564        break;
565      case ASDF_GET_ROWS:
566        $returned=array();
567        break;
568    }
569    if($this->dbHandle==null) return($returned);
570
571    $select=array('SUM(visits) AS nbVisits');
572    $groupBy=array();
573    // initialize fields list
574    foreach($fields as $field)
575    {
576      if($field=='IPadress' or
577         $field=='day' or
578         $field=='catId' or
579         $field=='country' or
580         $field=='uaType')
581      {
582        $select[]=$field;
583        $groupBy[]=$field;
584      }
585    }
586
587    // initialize filter
588    if(!is_array($filter)) $filter=array();
589
590    if(!isset($filter['IPadress'])) $filter['IPadress']=null;
591    if(!isset($filter['day'])) $filter['day']=null;
592    if(!isset($filter['uaType'])) $filter['uaType']=null;
593    if(!isset($filter['catId'])) $filter['catId']=null;
594    if(!isset($filter['country'])) $filter['country']=null;
595
596    $filter['IPadress']=$this->checkIPFilter($filter['IPadress']);
597    // check filter values - getOperator check and 'clean' the filter
598    $filter['IPadress']=$this->getOperator($filter['IPadress'], 'IP');
599    $filter['country']=$this->getOperator($filter['country'], 'string');
600    $filter['day']=$this->getOperator($filter['day'], 'integer');
601    $filter['uaType']=$this->getOperator($filter['uaType'], 'integer');
602    $filter['catId']=$this->getOperator($filter['catId'], 'integer');
603
604    // initialize order
605    $orderBy=array();
606    if(!is_array($order)) $order=array();
607    foreach($order as $sort)
608    {
609      if(isset($sort['id']) and isset($sort['direction']))
610      {
611        if((($sort['id']=='IPadress' or
612             $sort['id']=='catId' or
613             $sort['id']=='country' or
614             $sort['id']=='day' or
615             $sort['id']=='uaType' ) and
616            in_array($sort['id'], $select) or
617             $sort['id']=='nbVisits') and
618           ($sort['direction']=='A' or
619            $sort['direction']=='D')
620          ) $orderBy[]=$sort;
621      }
622    }
623    // set default order if nothing available is provided
624    if(count($orderBy)==0)
625    {
626      if(in_array('day', $select))
627        $orderBy[]=array('id'=>'day', 'direction'=>'A');
628      $orderBy[]=array('id'=>'nbVisits', 'direction'=>'D');
629    }
630
631    // build SELECT & GROUP By clauses
632    $select="SELECT ".implode(',', $select);
633    $groupBy=(count($groupBy)>0)?" GROUP BY ".implode(',', $groupBy):'';
634
635    //build ORDER BY clause
636    $orderBy=$this->buildOrderByClause($orderBy);
637
638    //build WHERE clause
639    $IPList=array();
640    $where=$this->buildWhereClause($filter, $IPList);
641
642    // build LIMIT clause
643    $limit=$this->buildLimitClause($page, $nbItemsPage);
644
645    // execute request
646    switch($mode)
647    {
648      case ASDF_GET_ROWS:
649          $sql=$select." FROM statip ".$where.$groupBy.$orderBy.$limit;
650
651          $sqlStm=$this->dbHandle->prepare($sql);
652          foreach($IPList as $num=>$IP)
653          {
654            $sqlStm->bindValue(':IP'.$num, $IP, SQLITE3_BLOB);
655          }
656
657          $result=$sqlStm->execute();
658          if($result)
659          {
660            while($row=$result->fetchArray(SQLITE3_ASSOC))
661            {
662              if(isset($row['IPadress']))
663                $row['IPadress']=self::IPBinaryDecode($row['IPadress']);
664              $returned[]=$row;
665            }
666          }
667        break;
668      case ASDF_GET_COUNT:
669          $sql="SELECT COUNT(*) AS nb
670                FROM statip $where;";
671
672          $sqlStm=$this->dbHandle->prepare($sql);
673          foreach($IPList as $num=>$IP)
674          {
675            $sqlStm->bindValue(':IP'.$num, $IP, SQLITE3_BLOB);
676          }
677
678          $result=$sqlStm->execute();
679          if($result)
680          {
681            while($row=$result->fetchArray(SQLITE3_ASSOC))
682            {
683              $returned=$row['nb'];
684            }
685          }
686        break;
687    }
688    return($returned);
689  }
690
691
692
693  /**
694   * returns stats from categories
695   *
696   * $page: the page number asked; first page is 1=>lower value means to get all values
697   * $nbItemsPage: the number of items returned per; 0 means no limit
698   *
699   *
700   * in ASDF_GET_ROWS mode, each returned logs is an array of asked fields
701   * at least, the following fields are always returned:
702   *  'catId'    => category Id
703   *  'nbVisits' => number of visits
704   *
705   * all fields are filterable, except 'nbVisits' that can't be filtered
706   *
707   * available fields values are:
708   *   'day'      => return detailled stat per day
709   *   'uaType'   => return detailled stat per browser type
710   *
711   * @param Integer $mode: type of result needed
712   *                          . ASDF_GET_ROWS return an array of logs
713   *                          . ASDF_GET_COUNT return the number of logs
714   * @param Integer $page: page number
715   * @param Integer $nbItemsPage: number of items per page
716   * @param Array $fields : additional fields to be returned
717   * @param Array $filter : filters to apply => see getLogs function for usage
718   * @param Array $order: sort to apply      => see getLogs function for usage; all fields can be sorted
719   * @return
720   */
721  public function getStatCat($mode=ASDF_GET_ROWS, $page=0, $nbItemsPage=0, $fields=array(), $filter=array(), $order=array())
722  {
723    switch($mode)
724    {
725      case ASDF_GET_COUNT:
726        $returned=0;
727        break;
728      case ASDF_GET_ROWS:
729        $returned=array();
730        break;
731    }
732    if($this->dbHandle==null) return($returned);
733
734    $select=array('catId', 'SUM(visits) AS nbVisits');
735    $groupBy=array('catId');
736    // initialize fields list
737    foreach($fields as $field)
738    {
739      if($field=='day' or
740         $field=='uaType')
741      {
742        $select[]=$field;
743        $groupBy[]=$field;
744      }
745    }
746
747    // initialize filter
748    if(!is_array($filter)) $filter=array();
749
750    if(!isset($filter['day'])) $filter['day']=null;
751    if(!isset($filter['uaType'])) $filter['uaType']=null;
752
753    // check filter values - getOperator check and 'clean' the filter
754    $filter['day']=$this->getOperator($filter['day'], 'integer');
755    $filter['uaType']=$this->getOperator($filter['uaType'], 'integer');
756
757
758    // initialize order
759    $orderBy=array();
760    if(!is_array($order)) $order=array();
761    foreach($order as $sort)
762    {
763      if(isset($sort['id']) and isset($sort['direction']))
764      {
765        if((($sort['id']=='day' or
766             $sort['id']=='uaType' ) and
767            in_array($sort['id'], $select) or
768             $sort['id']=='nbVisits') and
769           ($sort['direction']=='A' or
770            $sort['direction']=='D')
771          ) $orderBy[]=$sort;
772      }
773    }
774    // set default order if nothing available is provided
775    if(count($orderBy)==0)
776    {
777      if(in_array('day', $select))
778        $orderBy[]=array('id'=>'day', 'direction'=>'A');
779      $orderBy[]=array('id'=>'nbVisits', 'direction'=>'D');
780    }
781
782    // build SELECT & GROUP By clauses
783    $select="SELECT ".implode(',', $select);
784    $groupBy=(count($groupBy)>0)?" GROUP BY ".implode(',', $groupBy):'';
785
786    //build ORDER BY clause
787    $orderBy=$this->buildOrderByClause($orderBy);
788
789    //build WHERE clause
790    $IPList=array();
791    $where=$this->buildWhereClause($filter, $IPList);
792
793    // build LIMIT clause
794    $limit=$this->buildLimitClause($page, $nbItemsPage);
795
796    // execute request
797    switch($mode)
798    {
799      case ASDF_GET_ROWS:
800          $sql=$select." FROM statcategories ".$where.$groupBy.$orderBy.$limit;
801
802          $sqlStm=$this->dbHandle->prepare($sql);
803
804          $result=$sqlStm->execute();
805          if($result)
806          {
807            while($row=$result->fetchArray(SQLITE3_ASSOC))
808            {
809              $returned[]=$row;
810            }
811          }
812        break;
813      case ASDF_GET_COUNT:
814          $sql="SELECT COUNT(*) AS nb
815                FROM statcategories $where;";
816
817          $sqlStm=$this->dbHandle->prepare($sql);
818
819          $result=$sqlStm->execute();
820          if($result)
821          {
822            while($row=$result->fetchArray(SQLITE3_ASSOC))
823            {
824              $returned=$row['nb'];
825            }
826          }
827        break;
828    }
829    return($returned);
830  }
831
832
833
834
835  /**
836   * returns stats from images
837   *
838   *
839   * $page: the page number asked; first page is 1=>lower value means to get all values
840   * $nbItemsPage: the number of items returned per; 0 means no limit
841   *
842   *
843   * in ASDF_GET_ROWS mode, each returned logs is an array of asked fields
844   * at least, the following fields are always returned:
845   *  'imageId'  => image Id
846   *  'nbVisits' => number of visits
847   *
848   * all fields are filterable, except 'nbVisits' that can't be filtered
849   *
850   * available fields values are:
851   *   'day'      => return detailled stat per day
852   *   'uaType'   => return detailled stat per browser type
853   *   'catId'    => return detailled stat per categories (an image could be linked with more than one category)
854   *
855   * @param Integer $mode: type of result needed
856   *                          . ASDF_GET_ROWS return an array of logs
857   *                          . ASDF_GET_COUNT return the number of logs
858   * @param Integer $page: page number
859   * @param Integer $nbItemsPage: number of items per page
860   * @param Array $fields : additional fields to be returned
861   * @param Array $filter : filters to apply => see getLogs function for usage
862   * @param Array $order: sort to apply      => see getLogs function for usage; all fields can be sorted
863   * @return
864   */
865  public function getStatImages($mode=ASDF_GET_ROWS, $page=0, $nbItemsPage=0, $fields=array(), $filter=array(), $order=array())
866  {
867    switch($mode)
868    {
869      case ASDF_GET_COUNT:
870        $returned=0;
871        break;
872      case ASDF_GET_ROWS:
873        $returned=array();
874        break;
875    }
876    if($this->dbHandle==null) return($returned);
877
878    $select=array('imageId', 'SUM(visits) AS nbVisits');
879    $groupBy=array('imageId');
880    // initialize fields list
881    foreach($fields as $field)
882    {
883      if($field=='day' or
884         $field=='catId' or
885         $field=='uaType')
886      {
887        $select[]=$field;
888        $groupBy[]=$field;
889      }
890    }
891
892    // initialize filter
893    if(!is_array($filter)) $filter=array();
894
895    if(!isset($filter['day'])) $filter['day']=null;
896    if(!isset($filter['catId'])) $filter['catId']=null;
897    if(!isset($filter['uaType'])) $filter['uaType']=null;
898
899    // check filter values - getOperator check and 'clean' the filter
900    $filter['day']=$this->getOperator($filter['day'], 'integer');
901    $filter['catId']=$this->getOperator($filter['catId'], 'integer');
902    $filter['uaType']=$this->getOperator($filter['uaType'], 'integer');
903
904
905    // initialize order
906    $orderBy=array();
907    if(!is_array($order)) $order=array();
908    foreach($order as $sort)
909    {
910      if(isset($sort['id']) and isset($sort['direction']))
911      {
912        if((($sort['id']=='day' or
913             $sort['id']=='catId' or
914             $sort['id']=='uaType' ) and
915            in_array($sort['id'], $select) or
916             $sort['id']=='nbVisits') and
917           ($sort['direction']=='A' or
918            $sort['direction']=='D')
919          ) $orderBy[]=$sort;
920      }
921    }
922    // set default order if nothing available is provided
923    if(count($orderBy)==0)
924    {
925      if(in_array('day', $select))
926        $orderBy[]=array('id'=>'day', 'direction'=>'A');
927      $orderBy[]=array('id'=>'nbVisits', 'direction'=>'D');
928    }
929
930    // build SELECT & GROUP By clauses
931    $select="SELECT ".implode(',', $select);
932    $groupBy=(count($groupBy)>0)?" GROUP BY ".implode(',', $groupBy):'';
933
934    //build ORDER BY clause
935    $orderBy=$this->buildOrderByClause($orderBy);
936
937    //build WHERE clause
938    $IPList=array();
939    $where=$this->buildWhereClause($filter, $IPList);
940
941    // build LIMIT clause
942    $limit=$this->buildLimitClause($page, $nbItemsPage);
943
944    // execute request
945    switch($mode)
946    {
947      case ASDF_GET_ROWS:
948          $sql=$select." FROM statimages ".$where.$groupBy.$orderBy.$limit;
949
950          $sqlStm=$this->dbHandle->prepare($sql);
951
952          $result=$sqlStm->execute();
953          if($result)
954          {
955            while($row=$result->fetchArray(SQLITE3_ASSOC))
956            {
957              $returned[]=$row;
958            }
959          }
960        break;
961      case ASDF_GET_COUNT:
962          $sql="SELECT COUNT(*) AS nb
963                FROM statimages $where;";
964
965          $sqlStm=$this->dbHandle->prepare($sql);
966
967          $result=$sqlStm->execute();
968          if($result)
969          {
970            while($row=$result->fetchArray(SQLITE3_ASSOC))
971            {
972              $returned=$row['nb'];
973            }
974          }
975        break;
976    }
977    return($returned);
978  }
979
980
981
982
983
984
985  /**
986   * returns stats for a period
987   *
988   * $page: the page number asked; first page is 1=>lower value means to get all values
989   * $nbItemsPage: the number of items returned per; 0 means no limit
990   *
991   *
992   * each returned logs is an array of asked fields
993   * at least, the following fields are always returned:
994   *  'nbVisits' => number of visits
995   *
996   * all fields are filterable, except 'nbVisits' that can't be filtered
997   *
998   * available fields values are:
999   *   'day'       => return detailled stat per day
1000   *   'catId'     => return detailled stat per category
1001   *
1002   * @param Integer $page: page number
1003   * @param Integer $nbItemsPage: number of items per page
1004   * @param Array $fields : additional fields to be returned
1005   * @param Array $filter : filters to apply => see getLogs function for usage
1006   * @param Array $order: sort to apply      => see getLogs function for usage; all fields can be sorted
1007   * @return
1008   */
1009  public function getStatPeriod($page=0, $nbItemsPage=0, $fields=array(), $filter=array(), $order=array())
1010  {
1011    $returned=array();
1012    if($this->dbHandle==null) return($returned);
1013
1014    /*
1015     * total: 'T' variables
1016     * categories: 'C' variables
1017     * images 'I' variables
1018     * ip adresses: 'A' variables
1019     */
1020    $select=array(
1021      'T' => array('"T" AS nfoType', 'SUM(visits) AS nbVisits'),
1022      'C' => array('"C" AS nfoType', 'SUM(visits) AS nbVisits'),
1023      'I' => array('"I" AS nfoType', 'SUM(visits) AS nbVisits'),
1024      'A' => array('"A" AS nfoType', 'COUNT(DISTINCT IPadress) AS nbVisits')
1025    );
1026
1027    $groupBy=array();
1028    // initialize fields list
1029    foreach($fields as $field)
1030    {
1031      if($field=='day')
1032      {
1033        $select['T'][]=$field;
1034        $select['C'][]=$field;
1035        $select['I'][]=$field;
1036        $select['A'][]=$field;
1037        $groupBy[]=$field;
1038      }
1039    }
1040
1041    // initialize filter
1042    if(!is_array($filter)) $filter=array();
1043    $filter['T']=array();
1044    $filter['C']=array();
1045    $filter['I']=array();
1046    $filter['A']=array();
1047
1048    if(!isset($filter['day'])) $filter['day']=null;
1049    if(!isset($filter['catId'])) $filter['catId']=null;
1050
1051    foreach(array('T', 'C', 'I', 'A') as $key)
1052    {
1053      $filter[$key]['day']=$this->getOperator($filter['day'], 'integer');
1054      if($key=='C' and $filter['catId']==null)
1055      {
1056        $filter[$key]['catId']=$this->getOperator(array('operator' => '>', 'value' => 0), 'integer');
1057      }
1058      else
1059      {
1060        $filter[$key]['catId']=$this->getOperator($filter['catId'], 'integer');
1061      }
1062    }
1063
1064    // initialize order
1065    $orderBy=array();
1066    if(!is_array($order)) $order=array();
1067    foreach($order as $sort)
1068    {
1069      if(isset($sort['id']) and isset($sort['direction']))
1070      {
1071        if(($sort['id']=='day' and
1072            in_array($sort['id'], $select['T']) or
1073             $sort['id']=='nbVisits') and
1074           ($sort['direction']=='A' or
1075            $sort['direction']=='D')
1076          ) $orderBy[]=$sort;
1077      }
1078    }
1079    // set default order if nothing available is provided
1080    if(count($orderBy)==0)
1081    {
1082      if(in_array('day', $select['T']))
1083        $orderBy[]=array('id'=>'day', 'direction'=>'A');
1084      $orderBy[]=array('id'=>'nbVisits', 'direction'=>'D');
1085    }
1086
1087    // build SELECT & GROUP By clauses
1088    foreach($select as $key => $val)
1089    {
1090      $select[$key]="SELECT ".implode(',', $val);
1091    }
1092    $groupBy=(count($groupBy)>0)?" GROUP BY ".implode(',', $groupBy):'';
1093
1094    //build ORDER BY clause
1095    $orderBy=$this->buildOrderByClause($orderBy);
1096
1097    //build WHERE clause
1098    $IPList=array();
1099    $where=array(
1100      'T' => $this->buildWhereClause($filter['T'], $IPList),
1101      'C' => $this->buildWhereClause($filter['C'], $IPList),
1102      'I' => $this->buildWhereClause($filter['I'], $IPList),
1103      'A' => $this->buildWhereClause($filter['A'], $IPList)
1104    );
1105
1106    // build LIMIT clause
1107    $limit=$this->buildLimitClause($page, $nbItemsPage);
1108
1109
1110    $sql=$select['T']." FROM statcategories ".$where['T'].$groupBy;
1111    $sql.=' UNION '.$select['C']." FROM statcategories ".$where['C'].$groupBy;
1112    $sql.=' UNION '.$select['I']." FROM statimages ".$where['I'].$groupBy;
1113    $sql.=' UNION '.$select['A']." FROM statip ".$where['A'].$groupBy;
1114    $sql.=$orderBy;  //.$limit => removed because the limit have to be set on the total result
1115
1116    $sqlStm=$this->dbHandle->prepare($sql);
1117
1118    $result=$sqlStm->execute();
1119    if($result)
1120    {
1121      $sqlResult=array();
1122      while($row=$result->fetchArray(SQLITE3_ASSOC))
1123      {
1124        $sqlResult[]=$row;
1125      }
1126
1127      /*
1128       * $returned have a row per period & info type T,C,I,A
1129       *
1130       * example:
1131       *   01 T 25
1132       *   01 C 10
1133       *   01 I 45
1134       *   01 A 4
1135       *   14 T 8
1136       *   14 C 6
1137       *   14 A 1
1138       *   28 T 1
1139       *   28 A 1
1140       *
1141       * the result is built as a table with:
1142       *  - info type in column
1143       *  - missing periods
1144       *
1145       * example:
1146       *   period   T   C   I   A
1147       *   01       25  10  45  4
1148       *   02       0   0   0   0
1149       *   03       0   0   0   0
1150       *   04       0   0   0   0
1151       *   ...
1152       *   14       8   6   0   1
1153       *   ...
1154       *   28       1   0   0   1
1155       */
1156
1157      // first step, build a period list
1158      if(in_array('day', $fields))
1159      {
1160        for($d=1;$d<=$this->nbDaysMonth;$d++)
1161        {
1162          $returned[$d]=array(
1163            'T' => 0,
1164            'C' => 0,
1165            'I' => 0,
1166            'A' => 0
1167          );
1168        }
1169      }
1170      else
1171      {
1172        $returned=array(
1173          0 => array( // no day => 0
1174                'T' => 0,
1175                'C' => 0,
1176                'I' => 0,
1177                'A' => 0
1178            )
1179        );
1180      }
1181
1182      // next step, fill the table
1183      foreach($sqlResult as $row)
1184      {
1185        if(isset($row['day']))
1186        {
1187          $d=$row['day'];
1188        }
1189        else
1190        {
1191          $d=0;
1192        }
1193
1194        $returned[$d][$row['nfoType']]=$row['nbVisits'];
1195      }
1196
1197    }
1198    return($returned);
1199  }
1200
1201
1202
1203
1204
1205
1206
1207  /**
1208   * set country for IPadress in statip table
1209   *
1210   * @return Boolean: true if ok, otherwise false
1211   */
1212  public function buildIPCountry()
1213  {
1214    if($this->dbHandle==null or $this->ipCountryFile=='') return(false);
1215
1216    $result=$this->dbHandle->exec("ATTACH '".$this->ipCountryFile."' AS ipCountry");
1217    if($result)
1218    {
1219      /* -----------------------------------------------------------------------
1220       * SQLite doesn't allow to update a table with data from another table
1221       * sub-query is very slow, so the method:
1222       *  1) create an indexed temp table with the same structure than statip
1223       *  2) fill the temp table with records from statip table where country is empty
1224       *  3) do a select, join the temp table and the IP country table; completed result
1225       *     replace the content of the temp table
1226       *  4) records from temp table replace the linked records of the statip table
1227       *  5) delete temp table
1228       * ----------------------------------------------------------------------- */
1229
1230      $sql="
1231        -- start a transaction, if something is wrong database won't be poluted
1232        BEGIN TRANSACTION;
1233
1234        --log build command
1235        REPLACE INTO main.info (domain, key, value)
1236          VALUES('log',
1237                 'buildIPCountry()',
1238                 '".date('Y-m-d H:i:s')."');
1239
1240        UPDATE info
1241        SET value=value+1
1242        WHERE domain = 'log'
1243          AND key = 'buildIPCountry-count';
1244
1245        -- drop temp table if exists
1246        DROP TABLE IF EXISTS tmpIp;
1247
1248        -- create a temp table with records without country code
1249        CREATE TEMPORARY TABLE tmpIp AS
1250          SELECT * FROM statip WHERE country='';
1251        -- create index to optimize next requests
1252        CREATE INDEX iIpTmp ON tmpIp ('IPadress');
1253        CREATE UNIQUE INDEX iIpTmp2 ON tmpIp ('uaType', 'IPadress', 'catId', 'day');
1254
1255        -- set country for each record of the temp table
1256        REPLACE INTO tmpIp (uaType, IPadress, catId, `day`, visits, country)
1257          SELECT si.uaType, si.IPadress, si.catId, si.day, si.visits, il.country
1258          FROM ipCountry.iplist il, tmpIp si
1259          WHERE si.IPadress BETWEEN il.rangeStart AND il.rangeEnd;
1260
1261        -- set country for each record of the final table (from temp table)
1262        REPLACE INTO statip (uaType, IPadress, catId, `day`, visits, country)
1263          SELECT si.uaType, si.IPadress, si.catId, si.day, si.visits, si.country
1264          FROM tmpIp si;
1265
1266        -- delete temp table
1267        DROP TABLE IF EXISTS tmpIp;
1268
1269        -- update the logs table for rows with unset country
1270        -- use a simple sub select here, assuming that it's quick enough for the update
1271        UPDATE logs
1272        SET country=(SELECT sip.country FROM statip sip WHERE logs.IPadress = sip.IPadress)
1273        WHERE country='';
1274
1275        -- commit changes
1276        COMMIT TRANSACTION;
1277      ";
1278      $returned=$this->dbHandle->exec($sql);
1279
1280      if(!$this->dbHandle->exec("DETACH ipCountry")) $returned=false;
1281
1282      return($returned);
1283    }
1284    return(false);
1285  }
1286
1287
1288  /**
1289   * check the database schema; update it if needed
1290   *
1291   * @return Boolean: true if OK, otherwise false
1292   */
1293  protected function checkSchema()
1294  {
1295    if(!parent::checkSchema()) return(false);
1296
1297    $version=$this->getInfoProperty('nfo', 'version');
1298
1299    switch($version)
1300    {
1301      case '00.00.00':
1302        // version 00.00.00
1303        //  file is just created...
1304        $result=$this->getDBInfo(ASDF_DB_TYPE_TABLE, 'logs', ASDF_DB_INFO);
1305        if(count($result)==0)
1306        {
1307          $this->dbHandle->exec(
1308              "CREATE TABLE 'logs' (
1309                  'id' INTEGER PRIMARY KEY,
1310                  'date' INTEGER,
1311                  'IPadress' BLOB,
1312                  'country' TEXT,
1313                  'userId' INTEGER,
1314                  'catId' INTEGER,
1315                  'imageId' INTEGER,
1316                  'tagsId' TEXT,
1317                  'section' TEXT,
1318                  'userAgent' TEXT,
1319                  'uaBrowser' INTEGER,
1320                  'uaBrowserVersion' TEXT,
1321                  'uaEngine' INTEGER,
1322                  'uaEngineVersion' TEXT,
1323                  'uaOS' INTEGER,
1324                  'uaOSVersion' TEXT,
1325                  'uaType' INTEGER,
1326                  'screenSizeW' INTEGER,
1327                  'screenSizeH' INTEGER
1328              );"
1329            );
1330          $this->dbHandle->exec("CREATE INDEX iDateIP ON logs ('date', 'IPadress');");
1331          $this->dbHandle->exec("CREATE INDEX iIPCountry ON logs ('IPadress', 'country');");
1332          $this->dbHandle->exec("CREATE INDEX iUAB ON logs ('uaType', 'uaBrowser', 'uaEngine');");
1333          $this->dbHandle->exec("CREATE INDEX iUAO ON logs ('uaOS');");
1334        }
1335
1336        $result=$this->getDBInfo(ASDF_DB_TYPE_TABLE, 'statCategories', ASDF_DB_INFO);
1337        if(count($result)==0)
1338        {
1339          $this->dbHandle->exec(
1340              "CREATE TABLE 'statCategories' (
1341                  'catId' INTEGER,
1342                  'uaType' INTEGER,
1343                  'day' INTEGER,
1344                  'visits' INTEGER
1345              );"
1346            );
1347          $this->dbHandle->exec("CREATE UNIQUE INDEX iCat ON statCategories ('catId', 'uaType', 'day');");
1348        }
1349
1350        $result=$this->getDBInfo(ASDF_DB_TYPE_TABLE, 'statImages', ASDF_DB_INFO);
1351        if(count($result)==0)
1352        {
1353          $this->dbHandle->exec(
1354              "CREATE TABLE 'statImages' (
1355                  'imageId' INTEGER,
1356                  'catId' INTEGER,
1357                  'uaType' INTEGER,
1358                  'day' INTEGER,
1359                  'visits' INTEGER
1360              );"
1361            );
1362          $this->dbHandle->exec("CREATE UNIQUE INDEX iImg ON statImages ('imageId', 'catId', 'uaType', 'day');");
1363        }
1364
1365        $result=$this->getDBInfo(ASDF_DB_TYPE_TABLE, 'statIP', ASDF_DB_INFO);
1366        if(count($result)==0)
1367        {
1368          $this->dbHandle->exec(
1369              "CREATE TABLE 'statIP' (
1370                  'uaType' INTEGER,
1371                  'IPadress' BLOB,
1372                  'catId' INTEGER,
1373                  'day' INTEGER,
1374                  'visits' INTEGER,
1375                  'country' TEXT
1376              );"
1377            );
1378          $this->dbHandle->exec("CREATE UNIQUE INDEX iIP ON statIP ('uaType', 'IPadress', 'catId', 'day');");
1379          $this->dbHandle->exec("CREATE INDEX iIPAdress ON statIP ('IPadress');");
1380        }
1381
1382        $result=$this->getDBInfo(ASDF_DB_TYPE_TABLE, 'statUA', ASDF_DB_INFO);
1383        if(count($result)==0)
1384        {
1385          $this->dbHandle->exec(
1386              "CREATE TABLE 'statUA' (
1387                  'uaData' INTEGER,
1388                  'uaValue' INTEGER,
1389                  'uaVersion' TEXT,
1390                  'day' INTEGER,
1391                  'visits' INTEGER
1392              );"
1393            );
1394          $this->dbHandle->exec("CREATE UNIQUE INDEX iUA ON statUA ('uaData', 'uaValue', 'uaVersion', 'day');");
1395        }
1396
1397        if($this->getDBInfo(ASDF_DB_TYPE_TRIGGER, 'insertLogs')==0)
1398        {
1399          $this->dbHandle->exec("
1400            CREATE TRIGGER insertLogs
1401            AFTER INSERT ON logs
1402            BEGIN
1403              INSERT OR IGNORE INTO statCategories (catId, uaType, day, visits)
1404              VALUES (new.catId, new.uaType, strftime('%d',new.date, 'unixepoch', 'localtime'), 0);
1405
1406              UPDATE statCategories
1407              SET visits = visits+1
1408              WHERE catId = new.catId
1409                AND uaType = new.uaType
1410                AND day = strftime('%d',new.date, 'unixepoch', 'localtime');
1411
1412              INSERT OR IGNORE INTO statIP (uaType, IPadress, catId, day, visits, country)
1413              VALUES (new.uaType, new.IPadress, new.catId, strftime('%d',new.date, 'unixepoch', 'localtime'), 0, '');
1414
1415              UPDATE statIP
1416              SET visits = visits+1
1417              WHERE uaType = new.uaType
1418                AND IPadress = new.IPadress
1419                AND catId = new.catId
1420                AND day = strftime('%d',new.date, 'unixepoch', 'localtime');
1421
1422              -- multiple insert values doesn't work? then using select+union
1423              INSERT OR IGNORE INTO statUA (uaData, uaValue, uaVersion, day, visits)
1424                SELECT 1, new.uaBrowser, new.uaBrowserVersion, strftime('%d',new.date, 'unixepoch', 'localtime'), 0
1425                  UNION
1426                SELECT 2, new.uaEngine, new.uaEngineVersion, strftime('%d',new.date, 'unixepoch', 'localtime'), 0
1427                  UNION
1428                SELECT 3, new.uaOS, new.uaOSVersion, strftime('%d',new.date, 'unixepoch', 'localtime'), 0
1429                  UNION
1430                SELECT 49, new.uaType, '', strftime('%d',new.date, 'unixepoch', 'localtime'), 0;
1431
1432              -- note: 49=0x0031=UA_DATA_BROWSER_TYPE value
1433
1434              UPDATE statUA
1435              SET visits = visits+1
1436              WHERE uaData = 1 AND uaValue = new.uaBrowser AND uaVersion=new.uaBrowserVersion AND day = strftime('%d',new.date, 'unixepoch', 'localtime')
1437                OR uaData = 2 AND uaValue = new.uaEngine AND uaVersion=new.uaEngineVersion AND day = strftime('%d',new.date, 'unixepoch', 'localtime')
1438                OR uaData = 3 AND uaValue = new.uaOS AND uaVersion=new.uaOSVersion AND day = strftime('%d',new.date, 'unixepoch', 'localtime')
1439                OR uaData = 49 AND uaValue = new.uaType AND day = strftime('%d',new.date, 'unixepoch', 'localtime');
1440
1441            END;
1442          ");
1443        }
1444        if($this->getDBInfo(ASDF_DB_TYPE_TRIGGER, 'insertLogsImg')==0)
1445        {
1446          $this->dbHandle->exec("
1447            CREATE TRIGGER insertLogsImg
1448            AFTER INSERT ON logs
1449            WHEN new.imageId > 0
1450            BEGIN
1451              INSERT OR IGNORE INTO statImages (imageId, catId, uaType, day, visits)
1452              VALUES (new.imageId, new.catId, new.uaType, strftime('%d',new.date, 'unixepoch', 'localtime'), 0);
1453
1454              UPDATE statImages
1455              SET visits = visits+1
1456              WHERE imageId = new.imageId
1457                AND catId = new.catId
1458                AND uaType = new.uaType
1459                AND day = strftime('%d',new.date, 'unixepoch', 'localtime');
1460            END;
1461          ");
1462        }
1463
1464        $this->setInfoProperty('nfo', 'version', '01.00.00');
1465        return(true);
1466        break;
1467      default:
1468        break;
1469    }
1470    return(false);
1471  }
1472
1473} // class
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483?>
Note: See TracBrowser for help on using the repository browser.