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

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

First commit for EStat files

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