source: extensions/EStat/estat_ajax.php @ 17758

Last change on this file since 17758 was 17758, checked in by grum, 8 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: 77.9 KB
Line 
1<?php
2/*
3 * -----------------------------------------------------------------------------
4 * Plugin Name: EStat
5 * -----------------------------------------------------------------------------
6 * Author     : Grum
7 *   email    : grum@piwigo.org
8 *   website  : http://photos.grum.fr
9 *   PWG user : http://forum.piwigo.org/profile.php?id=3706
10 *
11 *   << May the Little SpaceFrog be with you ! >>
12 *
13 * -----------------------------------------------------------------------------
14 *
15 * See main.inc.php for release information
16 *
17 * manage all the ajax requests
18 * -----------------------------------------------------------------------------
19 */
20
21  // in this case, PHPWG_ROOT_PATH must be declared as an absolute path...
22  define('PHPWG_ROOT_PATH',dirname(dirname(dirname(__FILE__))).'/');
23  if(!defined('AJAX_CALL')) define('AJAX_CALL', true);
24
25  /*
26   * set ajax module in admin mode if request is used for admin interface
27   */
28  if(!isset($_REQUEST['ajaxfct'])) $_REQUEST['ajaxfct']='';
29  if(preg_match('/^admin\./i', $_REQUEST['ajaxfct'])) define('IN_ADMIN', true);
30
31  // the common.inc.php file loads all the main.inc.php plugins files
32  include_once(PHPWG_ROOT_PATH.'include/common.inc.php' );
33  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
34  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCUserAgent.class.inc.php');
35  include_once('estat_root.class.inc.php');
36
37  load_language('plugin.lang', ESTAT_PATH);
38
39
40  class EStat_Ajax extends EStat_root
41  {
42    const MAX_LOAD_LOG = 1000;
43
44    /**
45     * constructor
46     */
47    public function __construct($prefixeTable, $filelocation)
48    {
49      parent::__construct($prefixeTable, $filelocation);
50      $this->loadConfig();
51      $this->checkRequest();
52      $this->returnAjaxContent();
53    }
54
55    /**
56     * check the $_REQUEST values and set default values
57     *
58     */
59    protected function checkRequest()
60    {
61      global $user;
62
63      if(!isset($_REQUEST['errcode'])) $_REQUEST['errcode']='';
64      GPCAjax::checkToken();
65
66      // check if asked function is valid
67      if(!($_REQUEST[GPC_AJAX]=='admin.install.buildIpList' or
68           $_REQUEST[GPC_AJAX]=='admin.migrate.loadLogs' or
69           $_REQUEST[GPC_AJAX]=='admin.migrate.consolidate' or
70           $_REQUEST[GPC_AJAX]=='admin.migrate.finalize' or
71           $_REQUEST[GPC_AJAX]=='admin.stat.periodTreeList' or
72           $_REQUEST[GPC_AJAX]=='admin.stat.history.periodList' or
73           $_REQUEST[GPC_AJAX]=='admin.stat.history' or
74           $_REQUEST[GPC_AJAX]=='admin.stat.history.graphAllPeriods' or
75           $_REQUEST[GPC_AJAX]=='admin.stat.history.graphCurrentPeriod' or
76           $_REQUEST[GPC_AJAX]=='admin.stat.period' or
77           $_REQUEST[GPC_AJAX]=='admin.stat.period.graph' or
78           $_REQUEST[GPC_AJAX]=='admin.stat.ip' or
79           $_REQUEST[GPC_AJAX]=='admin.stat.ip.graphType' or
80           $_REQUEST[GPC_AJAX]=='admin.stat.ip.graphCountry' or
81           $_REQUEST[GPC_AJAX]=='admin.stat.category' or
82           $_REQUEST[GPC_AJAX]=='admin.stat.image' or
83           $_REQUEST[GPC_AJAX]=='admin.fct.validValues'
84           )) $_REQUEST[GPC_AJAX]='';
85
86      if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']) and !is_admin()) $_REQUEST['ajaxfct']='';
87
88      if($_REQUEST[GPC_AJAX]!='')
89      {
90        switch($_REQUEST[GPC_AJAX])
91        {
92          case 'admin.install.buildIpList':
93            if(!isset($_REQUEST['start'])) $_REQUEST['ajaxfct']='';
94            break;
95          case 'admin.migrate.loadLogs':
96            if(!isset($_REQUEST['lastId'])) $_REQUEST['lastId']=0;
97            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
98
99            if(!is_numeric($_REQUEST['lastId']) or
100               $_REQUEST['period']=='' or
101               !preg_match('/\\d{4}-\\d{2}/i', $_REQUEST['period'])) $_REQUEST['ajaxfct']='';
102            break;
103          case 'admin.migrate.consolidate':
104            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
105            if(!isset($_REQUEST['process'])) $_REQUEST['process']=0;
106
107            if(!is_numeric($_REQUEST['process']) or
108               $_REQUEST['period']=='' or
109               !preg_match('/\\d{4}-\\d{2}/i', $_REQUEST['period'])) $_REQUEST['ajaxfct']='';
110            break;
111          case 'admin.migrate.finalize':
112            break;
113          case 'admin.stat.history.periodList':
114            break;
115          case 'admin.stat.periodTreeList':
116            break;
117          case 'admin.stat.history':
118            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
119            if(!isset($_REQUEST['currentPage'])) $_REQUEST['currentPage']=0;
120            if(!isset($_REQUEST['nbItemsPage'])) $_REQUEST['nbItemsPage']=0;
121
122            if(!isset($_REQUEST['sort']))
123                $_REQUEST['sort']=array(
124                    array('direction' => 'A', 'id' => 'date')
125                );
126
127            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']=array();
128
129            if(!is_numeric($_REQUEST['currentPage']) or $_REQUEST['currentPage']<0) $_REQUEST['currentPage']=0;
130            if(!is_numeric($_REQUEST['nbItemsPage']) or $_REQUEST['nbItemsPage']<0) $_REQUEST['nbItemsPage']=50;
131
132            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
133            break;
134          case 'admin.stat.history.graphCurrentPeriod':
135            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
136            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
137            break;
138          case 'admin.stat.history.graphAllPeriods':
139            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
140            if(!isset($_REQUEST['nbMonth'])) $_REQUEST['nbMonth']=0;
141            break;
142          case 'admin.stat.period':
143            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
144            if(!isset($_REQUEST['currentPage'])) $_REQUEST['currentPage']=0;
145            if(!isset($_REQUEST['nbItemsPage'])) $_REQUEST['nbItemsPage']=0;
146
147            if(!isset($_REQUEST['sort']))
148                $_REQUEST['sort']=array(
149                    array('direction' => 'A', 'id' => 'year'),
150                    array('direction' => 'A', 'id' => 'month')
151                );
152
153            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
154
155            if(!is_numeric($_REQUEST['currentPage']) or $_REQUEST['currentPage']<0) $_REQUEST['currentPage']=0;
156            if(!is_numeric($_REQUEST['nbItemsPage']) or $_REQUEST['nbItemsPage']<0) $_REQUEST['nbItemsPage']=50;
157
158            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
159            $_REQUEST['filter']=$_REQUEST['additionalFilter'];
160            break;
161          case 'admin.stat.period.graph':
162            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
163
164            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
165
166            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
167            $_REQUEST['filter']=$_REQUEST['additionalFilter'];
168            break;
169          case 'admin.stat.ip':
170            if(!isset($_REQUEST['period'])) $_REQUEST['period']='a';
171            if(!isset($_REQUEST['currentPage'])) $_REQUEST['currentPage']=0;
172            if(!isset($_REQUEST['nbItemsPage'])) $_REQUEST['nbItemsPage']=0;
173
174            if(!isset($_REQUEST['group'])) $_REQUEST['group']=array();
175
176            if(!isset($_REQUEST['sort']))
177                $_REQUEST['sort']=array(
178                    array('direction' => 'A', 'id' => 'ip')
179                );
180
181            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
182            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']=array();
183
184            if(!is_numeric($_REQUEST['currentPage']) or $_REQUEST['currentPage']<0) $_REQUEST['currentPage']=0;
185            if(!is_numeric($_REQUEST['nbItemsPage']) or $_REQUEST['nbItemsPage']<0) $_REQUEST['nbItemsPage']=50;
186
187            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
188            $_REQUEST['filter']['additionalFilter']=$_REQUEST['additionalFilter'];
189            break;
190          case 'admin.stat.ip.graphType':
191            if(!isset($_REQUEST['period'])) $_REQUEST['period']='a';
192
193            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
194
195            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
196            $_REQUEST['filter']=$_REQUEST['additionalFilter'];
197            break;
198          case 'admin.stat.ip.graphCountry':
199            if(!isset($_REQUEST['period'])) $_REQUEST['period']='a';
200
201            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
202
203            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
204            $_REQUEST['filter']=$_REQUEST['additionalFilter'];
205            break;
206          case 'admin.stat.category':
207          case 'admin.stat.image':
208            if(!isset($_REQUEST['period'])) $_REQUEST['period']='a';
209            if(!isset($_REQUEST['currentPage'])) $_REQUEST['currentPage']=0;
210            if(!isset($_REQUEST['nbItemsPage'])) $_REQUEST['nbItemsPage']=0;
211
212            if(!isset($_REQUEST['group'])) $_REQUEST['group']=array();
213
214            if(!isset($_REQUEST['sort']))
215                $_REQUEST['sort']=array(
216                    array('direction' => 'A', 'id' => 'nbVisits')
217                );
218
219            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
220            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']=array();
221
222            if(!is_numeric($_REQUEST['currentPage']) or $_REQUEST['currentPage']<0) $_REQUEST['currentPage']=0;
223            if(!is_numeric($_REQUEST['nbItemsPage']) or $_REQUEST['nbItemsPage']<0) $_REQUEST['nbItemsPage']=50;
224
225            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
226            $_REQUEST['filter']['additionalFilter']=$_REQUEST['additionalFilter'];
227            break;
228          case 'admin.fct.validValues':
229            if(!isset($_REQUEST['domain'])) $_REQUEST['domain']='';
230            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']='';
231
232            if(!($_REQUEST['domain']=='uaBrowser' or
233                 $_REQUEST['domain']=='uaEngine' or
234                 $_REQUEST['domain']=='uaOS' or
235                 $_REQUEST['domain']=='uaType' or
236                 $_REQUEST['domain']=='country'))
237              $_REQUEST[GPC_AJAX]='';
238            break;
239          default:
240            $_REQUEST[GPC_AJAX]='';
241            break;
242        }
243
244      }
245    } //checkRequest
246
247
248    /**
249     * return ajax content
250     */
251    protected function returnAjaxContent()
252    {
253      $result="<p class='errors'>An error has occured [".$_REQUEST[GPC_AJAX]."]</p>";
254      switch($_REQUEST[GPC_AJAX])
255      {
256        case 'admin.install.buildIpList':
257          $result=$this->ajax_estat_admin_installBuildIpList($_REQUEST['start']);
258          break;
259        case 'admin.migrate.loadLogs':
260          $result=$this->ajax_estat_admin_migrateLoadLogs($_REQUEST['period'], $_REQUEST['lastId']);
261          break;
262        case 'admin.migrate.consolidate':
263          $result=$this->ajax_estat_admin_migrateConsolidate($_REQUEST['period'], $_REQUEST['process']);
264          break;
265        case 'admin.migrate.finalize':
266          $result=$this->ajax_estat_admin_migrateFinalize();
267          break;
268        case 'admin.stat.history':
269          $result=$this->ajax_estat_admin_statHistory($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['currentPage'], $_REQUEST['nbItemsPage']);
270          break;
271        case 'admin.stat.history.graphCurrentPeriod':
272          $result=$this->ajax_estat_admin_statHistoryGraphCurrentPeriod($_REQUEST['period']);
273          break;
274        case 'admin.stat.history.graphAllPeriods':
275          $result=$this->ajax_estat_admin_statHistoryVisitsAllPeriods($_REQUEST['period'], $_REQUEST['nbMonth']);
276          break;
277        case 'admin.stat.period':
278          $result=$this->ajax_estat_admin_statPeriod($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['currentPage'], $_REQUEST['nbItemsPage']);
279          break;
280        case 'admin.stat.period.graph':
281          $result=$this->ajax_estat_admin_statPeriodGraph($_REQUEST['period'], $_REQUEST['filter']);
282          break;
283        case 'admin.stat.ip':
284          $result=$this->ajax_estat_admin_statIP($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['group'], $_REQUEST['currentPage'], $_REQUEST['nbItemsPage']);
285          break;
286        case 'admin.stat.ip.graphType':
287          $result=$this->ajax_estat_admin_statIPGraphType($_REQUEST['period'], $_REQUEST['filter']);
288          break;
289        case 'admin.stat.ip.graphCountry':
290          $result=$this->ajax_estat_admin_statIPGraphCountry($_REQUEST['period'], $_REQUEST['filter']);
291          break;
292        case 'admin.stat.category':
293          $result=$this->ajax_estat_admin_statCategory($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['group'], $_REQUEST['currentPage'], $_REQUEST['nbItemsPage']);
294          break;
295        case 'admin.stat.image':
296          $result=$this->ajax_estat_admin_statImage($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['group'], $_REQUEST['currentPage'], $_REQUEST['nbItemsPage']);
297          break;
298
299//revoir les id des fonctions
300        case 'admin.stat.history.periodList':
301          $result=$this->ajax_estat_admin_statHistoryPeriodList();
302          break;
303        case 'admin.stat.periodTreeList':
304          $result=$this->ajax_estat_admin_statPeriodTreeList();
305          break;
306        case 'admin.fct.validValues':
307          $result=$this->ajax_estat_admin_fctValidValues($_REQUEST['domain'], $_REQUEST['filter']);
308          break;
309      }
310      GPCAjax::returnResult($result);
311    }
312
313
314    /*------------------------------------------------------------------------*
315     *
316     * ADMIN FUNCTIONS
317     *
318     *----------------------------------------------------------------------- */
319
320    /**
321     * import IP country file process
322     *
323     * return an array of informations
324     *  'nb'      => nb IP range processed for this call
325     *  'nbTotal' => nb total of IP range processed from the begining
326     *
327     * @param Integer start: IP range start load
328     * @return Array
329     */
330    protected function ajax_estat_admin_installBuildIpList($start)
331    {
332      $returned=array(
333        'nb' => 0,
334        'nbTotal' => 0
335      );
336
337      $dbCountry=new StatDBCountry($this->fileStatDir, self::FILE_COUNTRY);
338      if($dbCountry->open(ASDF_OPEN_WRITE))
339      {
340        $returned['nb']=$dbCountry->loadIpFile(ESTAT_PATH.'data/ipCountry.bin', $start, 5000);
341        $returned['nbTotal']=$dbCountry->getInfoProperty('nfo', 'numberOfIP');
342        $dbCountry->close();
343      }
344      return(json_encode($returned));
345    }
346
347
348
349    /**
350     * Migration process: import data from the history table
351     *
352     * @param String $period : period to be imported 'YYYY-MM'
353     * @param Longint $lastId : id to start
354     * @return String : an array in json format
355     *                    'lastId' => (Integer) the last Id processed in the history table
356     *                    'nbLogs' => (Integer) number of logs processed
357     */
358    protected function ajax_estat_admin_migrateLoadLogs($period, $lastId)
359    {
360      if(substr($period,5)>'12' or substr($period,5)<'01') return(-1);
361      $year=substr($period, 0,4);
362      $month=substr($period, 5);
363
364      $sql="SELECT id, date, time, user_id, IP, section, category_id, tag_ids, image_id, image_type
365            FROM ".HISTORY_TABLE."
366            WHERE id > $lastId
367              AND YEAR(`date`) = $year
368              AND MONTH(`date`) = $month
369            ORDER BY id
370            LIMIT 0,".self::MAX_LOAD_LOG;
371
372      $nbLogs=0;
373      $lastId=0;
374
375      $result=pwg_query($sql);
376      if($result)
377      {
378        // define file stat for the year/month period, open it ans start transaction
379        $monthStatFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
380        $monthStatFile->setPeriod($year, $month);
381        $monthStatFile->open(ASDF_OPEN_WRITE);
382        $monthStatFile->startTransac();
383
384        if($monthStatFile->getInfoProperty('log', 'startImport')==null)
385          $monthStatFile->setInfoProperty('log', 'startImport', date('Y-m-d H:i:s'));
386
387        // try to define from reverse DNS if IP is a crawler or not
388        $ipList=new ReverseIP();
389        //$ipList->loadIPFile($this->fileStatDir.'tmpIpFile.dat');
390
391        // build list of data to import
392        $list=array();      // items from history
393        $break=false;
394        while(!$break and $tmp=pwg_db_fetch_assoc($result))
395        {
396          if(substr($tmp['date'],0,7)==$period)
397          {
398            $list[]=$tmp;
399            $nbLogs++;
400            $lastId=$tmp['id'];
401
402            if($ipList->getIP($tmp['IP'])==-1)
403              $ipList->addIP($tmp['IP']);
404          }
405          else $break=true;
406        }
407
408        //$ipList->saveIPFile();
409
410
411        foreach($list as $val)
412        {
413          $uaType=$ipList->getIP($val['IP']);
414
415
416
417          $log=array(
418            'date' => strtotime($val['date']." ".$val['time']),
419            'IPadress' => $val['IP'],
420            'userId' => $val['user_id'],
421            'catId'  => $val['category_id'],
422            'imageId'  => ($val['image_id']!=null)?$val['image_id']:0,
423            'tagsId' => $val['tag_ids'],
424            'section' => $val['section'],
425
426            'userAgent' => '',
427            'uaBrowser' => ($uaType==UA_BROWSER_TYPE_CRAWLER)?UA_BOT_UNKNOWN:UA_BROWSER_UNKNOWN,
428            'uaBrowserVersion' => '',
429            'uaEngine' => UA_ENGINE_UNKNOWN,
430            'uaEngineVersion' => '',
431            'uaOS' => UA_OS_UNKNOWN,
432            'uaOSVersion' => '',
433            'uaType' => $uaType
434          );
435          $monthStatFile->addLog($log);
436        }
437
438
439        $monthStatFile->setInfoProperty('log', 'stopImport', date('Y-m-d H:i:s'));
440
441        // commit changes and close the file
442        $monthStatFile->stopTransac();
443        $monthStatFile->close();
444
445        // if imported data are from a previous period, pack it
446        if($nbLogs<self::MAX_LOAD_LOG and $period!=date('Y-m'))
447        {
448          /*if($monthStatFile->pack()===true)
449            $monthStatFile->delete(ASDF_DELETE_UNPACKED);*/
450        }
451      }
452
453      return(
454        json_encode(
455          Array(
456            'lastId' => $lastId,
457            'nbLogs' => $nbLogs
458          )
459        )
460      );
461    }
462
463
464    /**
465     * Migration process: consolidate logs on Global file
466     *
467     * @param String $period : period to consolidate (YYYY-MM)
468     * @param Integer $process : step
469     */
470    protected function ajax_estat_admin_migrateConsolidate($period, $process)
471    {
472      if(substr($period,5)>'12' or substr($period,5)<'01') return(-1);
473      $year=substr($period, 0,4);
474      $month=substr($period, 5);
475
476      $gStatFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
477      $gStatFile->setIpCountryFile($this->fileStatDir.'/'.self::FILE_COUNTRY.'.db', true);
478      $gStatFile->open(ASDF_OPEN_WRITE);
479      if($gStatFile->getInfoProperty('log', 'startImport')==null)
480        $gStatFile->setInfoProperty('log', 'startImport', date('Y-m-d H:i:s'));
481      $gStatFile->buildStatPeriod($this->fileStatDir, self::FILE_MONTH, $year, $month);
482      $gStatFile->setInfoProperty('log', 'stopImport', date('Y-m-d H:i:s'));
483      $gStatFile->close();
484
485      return('Y');
486    }
487
488    /**
489     * Migration process: finalize the migration
490     */
491    protected function ajax_estat_admin_migrateFinalize()
492    {
493      $this->config['plugin.newInstall']='n';
494      $this->saveConfig();
495      return('Y');
496    }
497
498
499    /**
500     * Return a list of available history periods
501     * @return String : an array in json format
502     *                  'value' => (String) the period in 'YYYY-MM' format
503     *                  'cols'  => (Array)
504     *                                (String) FileName prefix
505     *                                (String) Number of events in log file
506     */
507    protected function ajax_estat_admin_statHistoryPeriodList()
508    {
509      global $lang;
510
511      $returned=array();
512
513      $gStatFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
514      $gStatFile->open(ASDF_OPEN_READ);
515      $files=$gStatFile->getFilesList();
516      $gStatFile->close();
517
518      foreach($files as $file)
519      {
520        $returned[]=array(
521          'value' => sprintf('%04d%02d', $file['year'], $file['month']),
522          'cols' => array(
523                      $lang['month'][$file['month']].' '.$file['year'],
524                      $file['logs'].' '.l10n('estat_events')
525                    )
526        );
527      }
528
529      return(json_encode($returned));
530    }
531
532    /**
533     * return the logs events from a period
534     *
535     * @param String $period : the period to be processed 'YYYYMM'
536     * @param Array  $filter : filter options
537     * @param Integer $pageNumber : page number to return
538     * @return String : an array in json format
539     *                    (Array) events properties
540     *                      'date' => (String) date time in 'YYYY-MM-DD HH:II:SS' format
541     *                      'IpUserId' => (String) IP or user login
542     *                      'country' => (String) country code (ISO 3366-1)
543     *                      'catId' => (String) name of the album
544     *                      'imageId' => (String) name of image
545     *                      'tags' => (String) tags list
546     *                      'section' => (String) section name
547     *                      'uaEngine' => (String) browser: engine+version
548     *                      'uaBrowser' => (String) browser name+version
549     *                      'uaOS' => (String) browser os: name+version
550     *                      'uaType' => (String) browser type: name
551     *                      'userAgent' => (String) user agent string
552     */
553    protected function ajax_estat_admin_statHistory($period, $filterPost, $sort, $pageNumber, $nbItemsPage)
554    {
555      $year=substr($period,0,4);
556      $month=substr($period,4,2);
557
558      $filter=array();
559      foreach($filterPost as $val)
560      {
561        $filter[$val['id']]=$val;
562      }
563
564      // open db file for the period
565      $monthStatFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
566      $monthStatFile->setPeriod($year, $month);
567      $monthStatFile->open(ASDF_OPEN_READ);
568
569      // get history & total number of items
570      $returned=array(
571        'rows' => $monthStatFile->getLogs(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $filter, $sort),
572        'nbItems' => $monthStatFile->getLogs(ASDF_GET_COUNT, 0, 0, $filter, $sort)
573      );
574      $monthStatFile->close();
575
576      // prepare an EStat_IdList to buid a list of unique Id
577      $idList=new EStat_IdList(array('catId', 'imageId', 'tagsId', 'userId'));
578      // $idAssoc will get the label associated to the id
579      $idAssoc=array(
580        'catId'=>array(),
581        'imageId'=>array(),
582        'tagsId'=>array(),
583        'userId'=>array()
584      );
585
586      // build list of unique Id
587      foreach($returned['rows'] as $row)
588      {
589        $idList->addItems(
590          array(
591            'catId' => $row['catId'],
592            'imageId' => $row['imageId'],
593            'tagsId' => $row['tagsId'],
594            'userId' => $row['userId'],
595            'IPadress' => $row['IPadress']
596          )
597        );
598      }
599
600
601      if(count($idList->getItems('catId')) > 0)
602        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
603
604      if(count($idList->getItems('imageId')) > 0)
605        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
606
607      if(count($idList->getItems('tagsId')) > 0)
608        $this->prepareIdList($idAssoc, 'tagsId', "SELECT id, name FROM ".TAGS_TABLE." WHERE id IN (".implode(',', $idList->getItems('tagsId')).") ORDER BY id;");
609
610      if(count($idList->getItems('userId')) > 0)
611        $this->prepareIdList($idAssoc, 'userId', "SELECT id, username AS name FROM ".USERS_TABLE." WHERE id IN (".implode(',', $idList->getItems('userId')).") ORDER BY id;");
612
613      // complete the data
614      foreach($returned['rows'] as $key=>$row)
615      {
616        $userAgentNfo=GPCUserAgent::getProperties(
617            array(
618              UA_DATA_BROWSER => $row['uaBrowser'],
619              UA_DATA_BROWSER_TYPE => $row['uaType'],
620              UA_DATA_OS => $row['uaOS'],
621              UA_DATA_ENGINE => $row['uaEngine']
622            )
623          );
624
625        if($userAgentNfo[UA_DATA_ENGINE_NAME]=='Unknown') $userAgentNfo[UA_DATA_ENGINE_NAME]='ua_Unknown';
626        if($userAgentNfo[UA_DATA_BROWSER_NAME]=='Unknown') $userAgentNfo[UA_DATA_BROWSER_NAME]='ua_Unknown';
627        if($userAgentNfo[UA_DATA_OS_NAME]=='Unknown') $userAgentNfo[UA_DATA_OS_NAME]='ua_Unknown';
628
629        //$userAgent = UserAgent::parse($row['userAgent']);
630        $tmp=array(
631          'date' => date('Y-m-d H:i:s', $row['date']),
632          'IpUserId' => ($row['userId']==2)?$row['IPadress']:$this->getId($idAssoc, 'userId', $row['userId'], $row['IPadress'], 'name'),
633          'country' => $row['country'],
634          'catId' => GPCCore::getUserLanguageDesc($this->getId($idAssoc, 'catId', $row['catId'], ($row['catId']==0)?'-':'?')),
635          'imageId' => $this->getId($idAssoc, 'imageId', $row['imageId'], ($row['imageId']==0)?'-':'?', 'name'),
636          'tags'  => $this->getId($idAssoc, 'tagsId', $row['tagsId'], '', 'name'),
637          'section' => l10n($row['section']),
638          'uaEngine' => l10n($userAgentNfo[UA_DATA_ENGINE_NAME]),
639          'uaBrowser' => l10n($userAgentNfo[UA_DATA_BROWSER_NAME]),
640          'uaOS' => l10n($userAgentNfo[UA_DATA_OS_NAME]),
641          'uaType' => l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]),
642          'userAgent' => $row['userAgent']
643        );
644
645
646        if($userAgentNfo[UA_DATA_BROWSER_URL]!='')
647          $tmp['uaBrowser']='<a href="'.$userAgentNfo[UA_DATA_BROWSER_URL].'">'.$tmp['uaBrowser'].'</a>';
648
649        if($row['uaBrowserVersion']!='')
650          $tmp['uaBrowser'].=' <span class="version">'.$row['uaBrowserVersion'].'</span>';
651
652
653        if($userAgentNfo[UA_DATA_OS_URL]!='')
654          $tmp['uaOS']='<a href="'.$userAgentNfo[UA_DATA_OS_URL].'">'.$tmp['uaOS'].'</a>';
655
656        if($row['uaOSVersion']!='')
657          $tmp['uaOS'].=' <span class="version">'.$row['uaOSVersion'].'</span>';
658
659        if($userAgentNfo[UA_DATA_ENGINE_URL]!='')
660          $tmp['uaEngine']='<a href="'.$userAgentNfo[UA_DATA_ENGINE_URL].'">'.$tmp['uaEngine'].'</a>';
661
662        if($row['uaEngineVersion']!='')
663          $tmp['uaEngine'].=' <span class="version">'.$row['uaEngineVersion'].'</span>';
664
665        switch($tmp['catId'])
666        {
667          case '-':
668            break;
669          case '?':
670            $tmp['catId']=l10n('estat_unknown').'['.$row['catId'].']';
671            break;
672          default:
673            $tmp['catId']='<a href="'.GPCCore::urlBuild('admin.category', array('categoryId'=>$row['catId'])).'">'.$tmp['catId'].'</a>';
674            break;
675        }
676
677        $tmp['thumb']='';
678        switch($tmp['imageId'])
679        {
680          case '-':
681            break;
682          case '?':
683            $tmp['imageId']=l10n('estat_unknown').'['.$row['imageId'].']';
684            break;
685          default:
686            $tmp['imageId']='<a href="'.GPCCore::urlBuild('admin.picture', array('pictureId'=>$row['imageId'])).'">'.$tmp['imageId'].'</a>';
687            $imageNfo = new SrcImage(
688                          array(
689                            'id'=>$row['imageId'],
690                            'path'=>$this->getId($idAssoc, 'imageId', $row['imageId'], '', 'path')
691                          )
692                        );
693            $tmp['thumb']='./'.substr(DerivativeImage::url(IMG_THUMB, $imageNfo),strlen(PHPWG_ROOT_PATH));
694            break;
695        }
696
697        if($row['userId']==2)
698        {
699          if($this->config['logs.reverseDNS']=='y')
700          {/*
701            $reverseIp=$this->getId($idAssoc, 'IPadress', $tmp['IpUserId'], '?');
702            if($reverseIp!='?' and $reverseIp!='' and $reverseIp!=$tmp['IpUserId'])
703            {
704              $reverseIp=' ('.$reverseIp.')';
705            }
706            else
707            {
708              $reverseIp='';
709            }*/
710          }
711
712          if($row['country']!='--' and $row['country']!='XA')
713          {
714            $tmp['IpUserId'].='<span class="geoip">[<a href="http://www.geoiptool.com/fr/?IP='.$tmp['IpUserId'].'">'.$row['country'].'</a>]</span>';
715          }
716          else
717          {
718            //$tmp['IpUserId'].='<span class="geoip">[--]</span>';
719          }
720
721        }
722
723        $returned['rows'][$key]=array(
724          $tmp['date'],
725          $tmp['IpUserId'],
726          $tmp['catId'],
727          $tmp['imageId'],
728          $tmp['tags'],
729          $tmp['section'],
730          $tmp['uaBrowser'],
731          $tmp['uaEngine'],
732          $tmp['uaOS'],
733          $tmp['uaType'],
734          $tmp['userAgent'],
735          $tmp['thumb']
736        );
737      }
738      return(json_encode($returned));
739    }
740
741
742
743    /**
744     * return the number of logs events per day for the period
745     *
746     * @param String $period: period in 'YYYYMM' format
747     * @return String : an array in json format
748     *                    (Array)
749     *                      'axis' => (Array)  period as a formatted string
750     *                      'series' => (Array) serie values
751     *                      'maxValue' => (Integer) maximum value found on all series
752     */
753    protected function ajax_estat_admin_statHistoryGraphCurrentPeriod($period)
754    {
755      global $lang;
756
757      $returned=array(
758        'maxValue' => 0,
759        'axis' => array(),
760        'series' => array(
761                      'total'    => array(
762                                      'name' => l10n('estat_total'),
763                                      'nbVisits' => array()
764                                    ),
765                      'computer' => array(
766                                      'name' => l10n('ua_Computer'),
767                                      'nbVisits' => array()
768                                    ),
769                      'mobile'   => array(
770                                      'name' => l10n('ua_Mobile'),
771                                      'nbVisits' => array()
772                                    ),
773                      'crawler'  => array(
774                                      'name' => l10n('ua_Crawler'),
775                                      'nbVisits' => array()
776                                    ),
777                      'other' => array(
778                                      'name' => l10n('ua_Other'),
779                                      'nbVisits' => array()
780                                    )
781                    )
782      );
783
784      $year=substr($period, 0 ,4);
785      $month=substr($period, 4, 2);
786
787      // open db file for the period
788      $mStatFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
789      $mStatFile->setPeriod($year, $month);
790      $mStatFile->open(ASDF_OPEN_READ);
791
792      // get number of visits per type of user agent (mobile, computer, crawler, ...)
793      $data=$mStatFile->getStatUserAgent(ASDF_GET_ROWS, 0, 0,
794                                          array('day', 'uaValue'),
795                                          array('uaData' => array('operator'=>'=', 'value'=>UA_DATA_BROWSER_TYPE)),
796                                          array(
797                                            array('id'=>'day',  'direction'=>'A')
798                                          )
799                                        );
800      $mStatFile->close();
801
802      // nb of days for the period
803      $nbDay=$mStatFile->getNbDays();
804
805      // prepare data
806      $axis=array();
807      $series=array(
808          'total' => array(),
809          'computer' => array(),
810          'mobile' => array(),
811          'crawler' => array(),
812          'other' => array()
813        );
814
815      for($i=1;$i<=$nbDay;$i++)
816      {
817        $returned['axis'][]=$i;
818        $series['total'][$i]=0;
819        $series['computer'][$i]=0;
820        $series['mobile'][$i]=0;
821        $series['crawler'][$i]=0;
822        $series['other'][$i]=0;
823      }
824
825      foreach($data as $value)
826      {
827        $series['total'][$value['day']]+=$value['nbVisits'];
828        if($returned['maxValue']<$series['total'][$value['day']]) $returned['maxValue']=$series['total'][$value['day']];
829
830        switch($value['uaValue'])
831        {
832          case UA_BROWSER_TYPE_COMPUTER:
833            $series['computer'][$value['day']]+=$value['nbVisits'];
834            break;
835          case UA_BROWSER_TYPE_MOBILE:
836            $series['mobile'][$value['day']]+=$value['nbVisits'];
837            break;
838          case UA_BROWSER_TYPE_CRAWLER:
839            $series['crawler'][$value['day']]+=$value['nbVisits'];
840            break;
841          default:
842            $series['other'][$value['day']]+=$value['nbVisits'];
843            break;
844        }
845      }
846
847      // format axis (add day letter for sunday)
848      foreach($returned['axis'] as $key=>$day)
849      {
850        $period=$year.'-'.$month.'-'.$day;
851        if(date('w', strtotime($period))==0) $returned['axis'][$key]=l10n('letter_day_sunday').' '.$day;
852      }
853
854      // format series values
855      foreach($series as $serie=>$period)
856      {
857        foreach($period as $nbVisits)
858        {
859          $returned['series'][$serie]['nbVisits'][]=$nbVisits;
860        }
861      }
862
863      return(json_encode($returned));
864    }
865
866
867
868
869    /**
870     * return the number of logs events per period (for all periods)
871     *
872     * data can be filtered to retrieve informations from a limited range of $nbMonth around
873     * the $currentPeriod
874     *
875     * @param String $currentPeriod: current period (YYYYMM); no period=all periods
876     * @param Integer $nbMonth: number of month to retrieve; 0=all periods
877     * @return String : an array in json format
878     *                    (Array)
879     *                      'axis' => (Array)  period as a formatted string
880     *                      'series' => (Array) serie values
881     *                      'maxValue' => (Integer) maximum value found on all series
882     */
883    protected function ajax_estat_admin_statHistoryVisitsAllPeriods($currentPeriod='', $nbMonth=0)
884    {
885      if($currentPeriod!='' and $nbMonth>0)
886      {
887        $managePeriod=true;
888
889        $year=substr($currentPeriod,0,4);
890        $month=substr($currentPeriod,4,2);
891
892        $before=round($nbMonth/2,0);
893        $after=$nbMonth-$before-1;
894
895        $firstPeriod=date('Y-m', strtotime('-'.$before.' month', strtotime($year.'-'.$month.'-01')));
896        $lastPeriod=date('Y-m', strtotime('+'.$after.' month', strtotime($year.'-'.$month.'-01')));
897
898        $periodList=array();
899        for($i=0;$i<$nbMonth;$i++)
900        {
901          $period=date('Y-m', strtotime("+$i month", strtotime($firstPeriod.'-01')));
902          $periodList[$period]=array('y' => substr($period, 0, 4), 'm' => substr($period, 5, 2));
903        }
904      }
905      else
906      {
907        $managePeriod=false;
908        $before=0;
909        $after=0;
910        $year='';
911        $month='';
912        $firstPeriod='';
913        $lastPeriod='';
914        $periodList=array();
915      }
916
917      $returned=array(
918        'maxValue' => 0,
919        'axis' => array(),
920        'series' => array(
921                      'total'    => array(
922                                      'name' => l10n('estat_total'),
923                                      'nbVisits' => array()
924                                    ),
925                      'computer' => array(
926                                      'name' => l10n('ua_Computer'),
927                                      'nbVisits' => array()
928                                    ),
929                      'mobile'   => array(
930                                      'name' => l10n('ua_Mobile'),
931                                      'nbVisits' => array()
932                                    ),
933                      'crawler'  => array(
934                                      'name' => l10n('ua_Crawler'),
935                                      'nbVisits' => array()
936                                    ),
937                      'other' => array(
938                                      'name' => l10n('ua_Other'),
939                                      'nbVisits' => array()
940                                    )
941                    )
942      );
943
944      // open db file
945      $gStatFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
946      $gStatFile->open(ASDF_OPEN_READ);
947
948      // get number of visits per type of user agent (mobile, computer, crawler, ...)
949      $data=$gStatFile->getStatUserAgent(ASDF_GET_ROWS, 0, 0,
950                                          array('year', 'month', 'uaValue'),
951                                          array('uaData' => array('operator'=>'=', 'value'=>UA_DATA_BROWSER_TYPE)),
952                                          array(
953                                            array('id'=>'year',  'direction'=>'A'),
954                                            array('id'=>'month',  'direction'=>'A')
955                                          )
956                                        );
957      $gStatFile->close();
958
959
960      // prepare data
961      $axis=array();
962      $series=array(
963          'total' => array(),
964          'computer' => array(),
965          'mobile' => array(),
966          'crawler' => array(),
967          'other' => array()
968        );
969      if($managePeriod)
970      {
971        foreach($periodList as $period=>$value)
972        {
973          $axis[$period]=$value;
974          $series['total'][$period]=0;
975          $series['computer'][$period]=0;
976          $series['mobile'][$period]=0;
977          $series['crawler'][$period]=0;
978          $series['other'][$period]=0;
979        }
980      }
981
982      foreach($data as $value)
983      {
984        $value['month']=sprintf('%02d', 1*$value['month']);
985        $period=$value['year'].'-'.$value['month'];
986
987        if($managePeriod and isset($periodList[$period]) or !$managePeriod)
988        {
989          if($managePeriod) $periodList[$period]=true;
990
991          if(!isset($axis[$period]))
992          {
993            $axis[$period]=array('y'=>$value['year'], 'm'=>$value['month']);
994            $series['total'][$period]=0;
995            $series['computer'][$period]=0;
996            $series['mobile'][$period]=0;
997            $series['crawler'][$period]=0;
998            $series['other'][$period]=0;
999          }
1000
1001          $series['total'][$period]+=$value['nbVisits'];
1002          if($returned['maxValue']<$series['total'][$period]) $returned['maxValue']=$series['total'][$period];
1003
1004          switch($value['uaValue'])
1005          {
1006            case UA_BROWSER_TYPE_COMPUTER:
1007              $series['computer'][$period]+=$value['nbVisits'];
1008              break;
1009            case UA_BROWSER_TYPE_MOBILE:
1010              $series['mobile'][$period]+=$value['nbVisits'];
1011              break;
1012            case UA_BROWSER_TYPE_CRAWLER:
1013              $series['crawler'][$period]+=$value['nbVisits'];
1014              break;
1015            default:
1016              $series['other'][$period]+=$value['nbVisits'];
1017              break;
1018          }
1019        }
1020      }
1021
1022      // format axis values "month [year]"
1023      $i=0;
1024      foreach($axis as $period)
1025      {
1026        if($period['m']==1 or $i==0)
1027        {
1028          $returned['axis'][]='('.$period['y'].') '.l10n('month_'.$period['m']);
1029        }
1030        else
1031        {
1032          $returned['axis'][]=l10n('month_'.$period['m']);
1033        }
1034        $i++;
1035      }
1036
1037      // format series values
1038      foreach($series as $serie=>$period)
1039      {
1040        foreach($period as $nbVisits)
1041        {
1042          $returned['series'][$serie]['nbVisits'][]=$nbVisits;
1043        }
1044      }
1045
1046      return(json_encode($returned));
1047    }
1048
1049
1050    /**
1051     * return the number of visits from a period
1052     *
1053     * @param String $period : the period to be processed
1054     *                          'allYear'    => process all year
1055     *                          'y-YYYY'     => process year YYYY
1056     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1057     * @param Array  $filterPost : filter options
1058     * @param Integer $pageNumber : page number to return
1059     * @return String : an array in json format
1060     *                    (Array) visits properties
1061     *                      'period' => (String)
1062     *                      'nbPages' => (String) IP or user login
1063     *                      'nbCat' => (String) country code (ISO 3366-1)
1064     *                      'nbPhotos' => (String) name of the album
1065     *                      'nbIP' => (String) name of image
1066     */
1067    protected function ajax_estat_admin_statPeriod($period, $filterPost, $sort, $pageNumber, $nbItemsPage)
1068    {
1069      global $lang;
1070
1071      $periodType='';
1072      $year=null;
1073      $month=null;
1074
1075      $result=array(
1076        'rows'  => null,
1077        'total' => null
1078      );
1079      $returned=array(
1080        'rows'  => array(),
1081        'total' => array()
1082      );
1083      $fields=array(
1084        'rows' => array(),
1085        'total' => array()
1086      );
1087      $filter=array('uaData' => UA_DATA_BROWSER, 'catId' => array(), 'year'=>array(), 'month'=>array());
1088
1089      if(substr($period,0,3)=='ym-')
1090      {
1091        $periodType='ym';
1092        $year=substr($period,3,4)*1;
1093        $month=substr($period,7,2)*1;
1094        $fields['rows'][]='day';
1095      }
1096      elseif(substr($period,0,2)=='y-')
1097      {
1098        $periodType='y';
1099        $fields['rows'][]='month';
1100        $year=substr($period,2,4)*1;
1101      }
1102      else // all other values assume $period=='allYear'
1103      {
1104        $fields['rows'][]='year';
1105        $fields['total']=array();
1106      }
1107
1108      // filter on catId?
1109      if(isset($filterPost['catId']))
1110      {
1111        $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1112      }
1113      if($year!=null)
1114        $filter['year']=array('operator' => '=', 'value' => $year);
1115      if($month!=null)
1116        $filter['month']=array('operator' => '=', 'value' => $month);
1117
1118      // open db file for the period
1119
1120      if($periodType=='ym')
1121      {
1122        $statFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
1123        $statFile->setPeriod($year, sprintf('%02d', $month));
1124      }
1125      else
1126      {
1127        $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1128      }
1129
1130
1131      $statFile->open(ASDF_OPEN_READ);
1132
1133      // get stats
1134      $result['rows']=$statFile->getStatPeriod($pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
1135      // reformat stats for table
1136
1137      switch($periodType)
1138      {
1139        case 'ym':
1140          foreach($result['rows'] as $day => $values)
1141          {
1142            $returned['rows'][]=array(
1143              $day,
1144              $values['T'],
1145              $values['C'],
1146              $values['I'],
1147              $values['A'],
1148              $day
1149            );
1150          }
1151
1152          $tmp=$statFile->getStatPeriod(0, 0, $fields['total'], $filter, $sort);
1153          $returned['total']=array('', $tmp[0]['T'], $tmp[0]['C'], $tmp[0]['I'], $tmp[0]['A']);
1154          break;
1155        case 'y':
1156          foreach($result['rows'] as $year => $months)
1157          {
1158            foreach($months as $month => $values)
1159            {
1160              $returned['rows'][]=array(
1161                $lang['month'][$month],
1162                $values['T'],
1163                $values['C'],
1164                $values['I'],
1165                $values['A'],
1166                sprintf('%02d', $month)
1167              );
1168            }
1169          }
1170
1171          $tmp=$statFile->getStatPeriod(0, 0, $fields['total'], $filter, $sort);
1172          $returned['total']=array('', $tmp[0][0]['T'], $tmp[0][0]['C'], $tmp[0][0]['I'], $tmp[0][0]['A']);
1173          break;
1174        default:
1175          // all years...
1176          foreach($result['rows'] as $year => $values)
1177          {
1178            if($year>0)
1179            {
1180              $returned['rows'][]=array(
1181                $year,
1182                $values[0]['T'],
1183                $values[0]['C'],
1184                $values[0]['I'],
1185                $values[0]['A'],
1186                sprintf('%02d', $year)
1187              );
1188            }
1189          }
1190          $tmp=$statFile->getStatPeriod(0, 0, $fields['total'], $filter, $sort);
1191          $returned['total']=array('', $tmp[0][0]['T'], $tmp[0][0]['C'], $tmp[0][0]['I'], $tmp[0][0]['A']);
1192          break;
1193      }
1194
1195      $statFile->close();
1196      return(json_encode($returned));
1197    }
1198
1199
1200
1201
1202
1203    /**
1204     * return the number of visits from a period, formatted for a graph
1205     *
1206     * @param String $period : the period to be processed
1207     *                          'allYear'    => process all year
1208     *                          'y-YYYY'     => process year YYYY
1209     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1210     * @param Array  $filterPost : filter options
1211     * @param Integer $pageNumber : page number to return
1212     * @return String : an array in json format
1213     *                    (Array)
1214     *                      'axis' => (Array)  period as a formatted string
1215     *                      'series' => (Array) serie values
1216     *                      'maxValue' => (Integer) maximum value found on all series
1217     */
1218    protected function ajax_estat_admin_statPeriodGraph($period, $filterPost)
1219    {
1220      global $lang;
1221
1222      $periodType='';
1223      $year=null;
1224      $month=null;
1225
1226      $returned=array(
1227        'maxValue' => 0,
1228        'axis' => array(),
1229        'series' => array(
1230                      'viewedPages' => array(
1231                                      'name' => l10n('estat_viewedPages'),
1232                                      'nbVisits' => array()
1233                                    ),
1234                      'viewedAlbums' => array(
1235                                      'name' => l10n('estat_viewedAlbums'),
1236                                      'nbVisits' => array()
1237                                    ),
1238                      'viewedImages' => array(
1239                                      'name' => l10n('estat_viewedImages'),
1240                                      'nbVisits' => array()
1241                                    ),
1242                      'uniqueIP'  => array(
1243                                      'name' => l10n('estat_uniqueIP'),
1244                                      'nbVisits' => array()
1245                                    )
1246                    )
1247      );
1248
1249      $filter=array('uaData' => UA_DATA_BROWSER, 'catId' => array(), 'year'=>array(), 'month'=>array() );
1250      $fields=array();
1251
1252      if(substr($period,0,3)=='ym-')
1253      {
1254        $periodType='ym';
1255        $year=substr($period,3,4)*1;
1256        $month=substr($period,7,2)*1;
1257        $fields[]='day';
1258      }
1259      elseif(substr($period,0,2)=='y-')
1260      {
1261        $periodType='y';
1262        $fields[]='month';
1263        $year=substr($period,2,4)*1;
1264      }
1265      else // all other values assume $period=='allYear'
1266      {
1267        $fields[]='year';
1268      }
1269
1270      // filter on catId?
1271      if(isset($filterPost['catId']))
1272      {
1273        $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1274      }
1275      if($year)
1276        $filter['year']=array('operator' => '=', 'value' => $year);
1277      if($month)
1278        $filter['month']=array('operator' => '=', 'value' => $month);
1279
1280
1281      // open db file for the period
1282
1283      if($periodType=='ym')
1284      {
1285        $statFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
1286        $statFile->setPeriod($year, sprintf('%02d', $month));
1287      }
1288      else
1289      {
1290        $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1291      }
1292
1293
1294      $statFile->open(ASDF_OPEN_READ);
1295
1296      // get stats
1297      $result['rows']=$statFile->getStatPeriod(0, 0, $fields, $filter, null);
1298
1299
1300      // prepare data
1301      $axis=array();
1302      $series=array(
1303          'viewedPages' => array(),
1304          'viewedAlbums' => array(),
1305          'viewedImages' => array(),
1306          'uniqueIP' => array()
1307        );
1308
1309      switch($periodType)
1310      {
1311        case 'ym':
1312          foreach($result['rows'] as $day => $values)
1313          {
1314            if($returned['maxValue']<$values['T']) $returned['maxValue']=$values['T'];
1315            $returned['axis'][]=$day;
1316            $series['viewedPages'][$day]=$values['T'];
1317            $series['viewedAlbums'][$day]=$values['C'];
1318            $series['viewedImages'][$day]=$values['I'];
1319            $series['uniqueIP'][$day]=$values['A'];
1320          }
1321
1322          // format axis (add day letter for sunday)
1323          foreach($returned['axis'] as $key=>$day)
1324          {
1325            $period=$year.'-'.$month.'-'.$day;
1326            if(date('w', strtotime($period))==0) $returned['axis'][$key]=l10n('letter_day_sunday').' '.$day;
1327          }
1328          break;
1329        case 'y':
1330          foreach($result['rows'] as $year => $months)
1331          {
1332            foreach($months as $month => $values)
1333            {
1334              if($returned['maxValue']<$values['T']) $returned['maxValue']=$values['T'];
1335              $returned['axis'][]=$lang['month'][$month];
1336              $series['viewedPages'][$month]=$values['T'];
1337              $series['viewedAlbums'][$month]=$values['C'];
1338              $series['viewedImages'][$month]=$values['I'];
1339              $series['uniqueIP'][$month]=$values['A'];
1340            }
1341          }
1342          break;
1343        default:
1344          foreach($result['rows'] as $year => $values)
1345          {
1346            if($year>0)
1347            {
1348              if($returned['maxValue']<$values[0]['T']) $returned['maxValue']=$values[0]['T'];
1349              $returned['axis'][]=$year;
1350              $series['viewedPages'][$year]=$values[0]['T'];
1351              $series['viewedAlbums'][$year]=$values[0]['C'];
1352              $series['viewedImages'][$year]=$values[0]['I'];
1353              $series['uniqueIP'][$year]=$values[0]['A'];
1354            }
1355          }
1356          break;
1357      }
1358
1359      // format series values
1360      foreach($series as $serie=>$period)
1361      {
1362        foreach($period as $nbVisits)
1363        {
1364          $returned['series'][$serie]['nbVisits'][]=$nbVisits;
1365        }
1366      }
1367
1368      return(json_encode($returned));
1369    }
1370
1371
1372
1373
1374
1375    /**
1376     * return the detail for IP from a period
1377     *
1378     * @param String $period : the period to be processed
1379     *                          'allYear'    => process all year
1380     *                          'y-YYYY'     => process year YYYY
1381     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1382     * @param Array  $filterPost : filter options
1383     * @param Array  $sort: sort options
1384     * @param Array  $group: grouped items; could be:
1385     *                        'IPadress'
1386     *                        'country'
1387     *                        'uaType'
1388     * @param Integer $pageNumber : page number to return
1389     * @return String : an array in json format
1390     *                    (Array)
1391     *                      'rows' => (Array)
1392     *                                  'IPadress' => (String)
1393     *                                  'country' => (String)
1394     *                                  'uaType' => (String)
1395     *                                  'nbVisits' => (Integer)
1396     *                      'total' => (Array)
1397     *                                  'IPadress' => (String) [empty]
1398     *                                  'country' => (String) [empty]
1399     *                                  'uaType' => (String) [empty]
1400     *                                  'nbVisits' => (Integer)
1401     *                      'nbItems' => (Integer)
1402     */
1403    protected function ajax_estat_admin_statIP($period, $filterPost, $sort, $group, $pageNumber, $nbItemsPage)
1404    {
1405      global $lang;
1406
1407      $year=null;
1408      $month=null;
1409
1410      $result=array(
1411        'rows'  => array(),
1412        'total' => array()
1413      );
1414      $returned=array(
1415        'rows'  => array(),
1416        'total' => array(),
1417        'nbItems' => 0
1418      );
1419      $fields=array(
1420        'rows' => array_diff(array('uaType', 'IPadress', 'country'), $group),
1421        'total' => array()
1422      );
1423      $filter=array();
1424
1425      if(substr($period,0,3)=='ym-')
1426      {
1427        $year=substr($period,3,4)*1;
1428        $month=substr($period,7,2)*1;
1429      }
1430      elseif(substr($period,0,2)=='y-')
1431      {
1432        $year=substr($period,2,4)*1;
1433      }
1434
1435      foreach($filterPost as $key => $val)
1436      {
1437        if($key==='additionalFilter')
1438        {
1439          if(isset($val['catId']))
1440            $filter['catId']=$this->buildCatIdFilter($val['catId']);
1441        }
1442        else
1443        {
1444          $filter[$val['id']]=$val;
1445        }
1446      }
1447
1448      if($year!=null)
1449        $filter['year']=array('operator' => '=', 'value' => $year);
1450      if($month!=null)
1451        $filter['month']=array('operator' => '=', 'value' => $month);
1452
1453      // open db file for the period
1454
1455
1456      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1457
1458      $statFile->open(ASDF_OPEN_READ);
1459
1460      // get stats
1461      $result['rows']=$statFile->getStatIP(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
1462      $result['total']=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, array(), $filter, array());
1463
1464      foreach($result['rows'] as $row)
1465      {
1466        if(isset($row['uaType']))
1467        {
1468          $userAgentNfo=GPCUserAgent::getProperties(
1469              array(
1470                UA_DATA_BROWSER_TYPE => $row['uaType']
1471              )
1472            );
1473          $row['uaType']=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
1474        }
1475        else
1476        {
1477          $row['uaType']='';
1478        }
1479
1480        if(isset($row['country']))
1481        {
1482          $country='estat_country_'.strtoupper($row['country']);
1483          if(isset($lang[$country]))
1484          {
1485            $country="<span class='cCountryCode'>".$row['country'].'</span>'.$lang[$country];
1486          }
1487          else
1488          {
1489            $country="<span class='cCountryCode'>".$row['country'].'</span>';
1490          }
1491        }
1492        else
1493        {
1494          $country='';
1495          $row['country']='';
1496        }
1497
1498        if(isset($row['IPadress']))
1499        {
1500          if($row['country']!='--' and $row['country']!='XA')
1501          {
1502            $row['IPadress']='<a href="http://www.geoiptool.com/fr/?IP='.$row['IPadress'].'">'.$row['IPadress'].'</a>';
1503          }
1504        }
1505        else
1506        {
1507          $row['IPadress']='';
1508        }
1509
1510        $returned['rows'][]=array(
1511          $row['IPadress'],
1512          $country,
1513          $row['uaType'],
1514          sprintf('%d<span class="cPctCol">%0.2f%%</span>', $row['nbVisits'], 100*$row['nbVisits']/$result['total'][0]['nbVisits'])
1515        );
1516      }
1517
1518      $returned['total']=array(
1519        '', '', '',
1520        isset($result['total'][0]['nbVisits'])?$result['total'][0]['nbVisits']:'0'
1521      );
1522
1523      $returned['nbItems']=$statFile->getStatIP(ASDF_GET_COUNT, 0, 0, $fields['rows'], $filter, array());
1524
1525      $statFile->close();
1526      return(json_encode($returned));
1527    }
1528
1529
1530
1531    /**
1532     * return the detail needed to draw a GraphType for IP from a period
1533     *
1534     * @param String $period : the period to be processed
1535     *                          'allYear'    => process all year
1536     *                          'y-YYYY'     => process year YYYY
1537     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1538     * @param Array  $filterPost : filter options
1539     * @return String : an array in json format
1540     *                    (Array)
1541     *                      'values'       => (Array) (Integer)
1542     *                      'valuesLabels' => (Array) (String)
1543     */
1544    protected function ajax_estat_admin_statIPGraphType($period, $filterPost)
1545    {
1546      global $lang;
1547
1548      $year=null;
1549      $month=null;
1550
1551      $returned=array(
1552        'values' => array(0,0,0,0,0),
1553        'valuesLabels' => array(
1554            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_CRAWLER]),
1555            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_COMPUTER]),
1556            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_MOBILE]),
1557            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_CONSOLE]),
1558            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_UNKNOWN])
1559        )
1560      );
1561      $fields=array('uaType');
1562
1563      $filter=array();
1564
1565      if(substr($period,0,3)=='ym-')
1566      {
1567        $year=substr($period,3,4)*1;
1568        $month=substr($period,7,2)*1;
1569      }
1570      elseif(substr($period,0,2)=='y-')
1571      {
1572        $year=substr($period,2,4)*1;
1573      }
1574
1575      if(isset($filterPost['catId']))
1576          $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1577
1578      if($year!=null)
1579        $filter['year']=array('operator' => '=', 'value' => $year);
1580      if($month!=null)
1581        $filter['month']=array('operator' => '=', 'value' => $month);
1582
1583      $sort=array(
1584        array('id'=>'uaType', 'direction'=>'A')
1585      );
1586
1587      // open db file for the period
1588      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1589
1590      $statFile->open(ASDF_OPEN_READ);
1591
1592      // get stats
1593      $result=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, $fields, $filter, $sort);
1594      $statFile->close();
1595
1596      $sum=0;
1597      foreach($result as $row)
1598      {
1599        switch($row['uaType'])
1600        {
1601          case UA_BROWSER_TYPE_CRAWLER:
1602            $key=0;
1603            break;
1604          case UA_BROWSER_TYPE_COMPUTER:
1605            $key=1;
1606            break;
1607          case UA_BROWSER_TYPE_MOBILE:
1608            $key=2;
1609            break;
1610          case UA_BROWSER_TYPE_CONSOLE:
1611            $key=3;
1612            break;
1613          case UA_BROWSER_TYPE_UNKNOWN:
1614            $key=4;
1615            break;
1616        }
1617
1618        $returned['values'][$key]=$row['nbVisits'];
1619        $sum+=$row['nbVisits'];
1620      }
1621
1622      foreach($returned['values'] as $key => $val)
1623      {
1624        if($val>0)
1625          $returned['valuesLabels'][$key].=sprintf(' (%0.2f%%)', 100*$val/$sum);
1626      }
1627
1628      return(json_encode($returned));
1629    }
1630
1631
1632
1633
1634
1635    /**
1636     * return the detail needed to draw a GraphCountry for IP from a period
1637     *
1638     * @param String $period : the period to be processed
1639     *                          'allYear'    => process all year
1640     *                          'y-YYYY'     => process year YYYY
1641     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1642     * @param Array  $filterPost : filter options
1643     * @return String : an array in json format
1644     *                    (Array)
1645     *                      'values'       => (Array) (Integer)
1646     *                      'valuesLabels' => (Array) (String)
1647     */
1648    protected function ajax_estat_admin_statIPGraphCountry($period, $filterPost)
1649    {
1650      global $lang;
1651
1652      $year=null;
1653      $month=null;
1654
1655      $returned=array(
1656        'values' => array(),
1657        'valuesLabels' => array()
1658      );
1659      $fields=array('country');
1660
1661      $filter=array();
1662
1663      if(substr($period,0,3)=='ym-')
1664      {
1665        $year=substr($period,3,4)*1;
1666        $month=substr($period,7,2)*1;
1667      }
1668      elseif(substr($period,0,2)=='y-')
1669      {
1670        $year=substr($period,2,4)*1;
1671      }
1672
1673      if(isset($filterPost['catId']))
1674          $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1675
1676      if($year!=null)
1677        $filter['year']=array('operator' => '=', 'value' => $year);
1678      if($month!=null)
1679        $filter['month']=array('operator' => '=', 'value' => $month);
1680
1681      // open db file for the period
1682      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1683
1684      $statFile->open(ASDF_OPEN_READ);
1685
1686      // get stats
1687      $result=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, $fields, $filter);
1688      $statFile->close();
1689
1690      $sum=0;
1691      foreach($result as $row)
1692      {
1693        $sum+=$row['nbVisits'];
1694      }
1695
1696      $i=0;
1697      $nb=0;
1698      $other=-1;
1699      foreach($result as $row)
1700      {
1701        $pct=100*$row['nbVisits']/$sum;
1702
1703        if($i<9 and $pct>=0.5)
1704        {
1705          $country='estat_country_'.strtoupper($row['country']);
1706          if(isset($lang[$country]))
1707          {
1708            $country=$row['country'].' - '.$lang[$country];
1709          }
1710          else
1711          {
1712            $country=$row['country'];
1713          }
1714
1715          $country.=sprintf(' (%0.2f%%)', $pct);
1716
1717          $returned['values'][$i]=$row['nbVisits'];
1718          $returned['valuesLabels'][$i]=$country;
1719          $i++;
1720        }
1721        else
1722        {
1723          $nb++;
1724          $other=$i;
1725          if(!isset($returned['values'][$i]))
1726          {
1727            $returned['values'][$i]=0;
1728            $returned['valuesLabels'][$i]=l10n('estat_Other');
1729          }
1730          $returned['values'][$i]+=$row['nbVisits'];
1731        }
1732      }
1733
1734      if($other>-1)
1735      {
1736        $nbCountry=l10n('estat_country_nb');
1737        if($nb>1)
1738          $nbCountry=l10n('estat_countries_nb');
1739
1740        $returned['valuesLabels'][$other].=sprintf(' ('.$nbCountry.', %0.2f%%)', $nb, 100*$returned['values'][$other]/$sum );
1741      }
1742
1743      return(json_encode($returned));
1744    }
1745
1746
1747
1748
1749
1750    /**
1751     * return the detail for albums/categories from a period
1752     *
1753     * @param String $period : the period to be processed
1754     *                          'allYear'    => process all year
1755     *                          'y-YYYY'     => process year YYYY
1756     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1757     * @param Array  $filterPost : filter options
1758     * @param Array  $sort: sort options
1759     * @param Array  $group: grouped items; could be:
1760     *                        'uaType'
1761     * @param Integer $pageNumber : page number to return
1762     * @return String : an array in json format
1763     *                    (Array)
1764     *                      'rows' => (Array)
1765     *                                  'category' => (String)
1766     *                                  'uaType' => (String)
1767     *                                  'nbVisits' => (Integer)
1768     *                      'total' => (Array)
1769     *                                  'category' => (String) [empty]
1770     *                                  'uaType' => (String) [empty]
1771     *                                  'nbVisits' => (Integer)
1772     *                      'nbItems' => (Integer)
1773     */
1774    protected function ajax_estat_admin_statCategory($period, $filterPost, $sort, $group, $pageNumber, $nbItemsPage)
1775    {
1776      global $lang;
1777
1778      $year=null;
1779      $month=null;
1780
1781      $result=array(
1782        'rows'  => array(),
1783        'total' => array()
1784      );
1785      $returned=array(
1786        'rows'  => array(),
1787        'total' => array(),
1788        'nbItems' => 0
1789      );
1790      $fields=array(
1791        'rows' => array_diff(array('catId', 'uaType'), $group),
1792        'total' => array()
1793      );
1794      $filter=array();
1795
1796      if(substr($period,0,3)=='ym-')
1797      {
1798        $year=substr($period,3,4)*1;
1799        $month=substr($period,7,2)*1;
1800      }
1801      elseif(substr($period,0,2)=='y-')
1802      {
1803        $year=substr($period,2,4)*1;
1804      }
1805
1806      foreach($filterPost as $key => $val)
1807      {
1808        if($key==='additionalFilter')
1809        {
1810          if(isset($val['catId']))
1811            $filter['catId']=$this->buildCatIdFilter($val['catId']);
1812        }
1813        else
1814        {
1815          $filter[$val['id']]=$val;
1816        }
1817      }
1818
1819      if($year!=null)
1820        $filter['year']=array('operator' => '=', 'value' => $year);
1821      if($month!=null)
1822        $filter['month']=array('operator' => '=', 'value' => $month);
1823
1824      // open db file for the period
1825
1826
1827      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1828
1829      $statFile->open(ASDF_OPEN_READ);
1830
1831      // get stats
1832      $result['rows']=$statFile->getStatCat(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
1833      $result['total']=$statFile->getStatCat(ASDF_GET_ROWS, 0, 0, array(), $filter, array());
1834
1835      // prepare categories&images properties
1836      $idList=new EStat_IdList(array('catId', 'imageId'));
1837      $idAssoc=array(
1838        'catId'=>array(),
1839        'imageId'=>array()
1840      );
1841
1842      // first, build category_id list
1843      foreach($result['rows'] as $row)
1844      {
1845        $idList->addItems(array('catId' => $row['catId']));
1846      }
1847
1848      // get upper categories and complete category_id list
1849      if(count($idList->getItems('catId')) > 0)
1850      {
1851        $sql="SELECT DISTINCT uppercats FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).");";
1852        $result2=pwg_query($sql);
1853        if($result2)
1854        {
1855          while($row=pwg_db_fetch_row($result2))
1856          {
1857            $ids=explode(',', $row[0]);
1858            foreach($ids as $id)
1859            {
1860              $idList->addItems(array('catId' => $id));
1861            }
1862          }
1863        }
1864      }
1865
1866      // get all needed properties for each category_id
1867      if(count($idList->getItems('catId')) > 0)
1868        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name, uppercats, representative_picture_id FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
1869
1870      // prepare image_id informations (for category representative picture)
1871      $categories=$idList->getItems('catId');
1872      foreach($idAssoc['catId'] as $category)
1873      {
1874        if($category['representative_picture_id']!=null)
1875          $idList->addItems(array('imageId' => $category['representative_picture_id']));
1876      }
1877
1878      if(count($idList->getItems('imageId')) > 0)
1879        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
1880
1881      foreach($result['rows'] as $row)
1882      {
1883        if(isset($row['uaType']))
1884        {
1885          $userAgentNfo=GPCUserAgent::getProperties(
1886              array(
1887                UA_DATA_BROWSER_TYPE => $row['uaType']
1888              )
1889            );
1890          $row['uaType']=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
1891        }
1892        else
1893        {
1894          $row['uaType']='';
1895        }
1896
1897
1898        if($row['catId']==0)
1899        {
1900          $categoryNfo=l10n('estat_special_category');
1901        }
1902        elseif($this->getId($idAssoc, 'catId', $row['catId'], '', 'name')=='')
1903        {
1904          $categoryNfo=l10n('estat_deleted_category');
1905        }
1906        else
1907        {
1908          $categoryNfo='<a href="'.GPCCore::urlBuild('admin.album', array('categoryId'=>$row['catId'])).'">'.$this->getId($idAssoc, 'catId', $row['catId'], '', 'name').'</a>';
1909        }
1910
1911        $uppercats=explode(',', $this->getId($idAssoc, 'catId', $row['catId'], null, 'uppercats'));
1912        if(count($uppercats)>1)
1913        {
1914          $categoryNfo=$this->getId($idAssoc, 'catId', $uppercats[count($uppercats)-2], '', 'name')." / ".$categoryNfo;
1915        }
1916
1917        $representativeUrl=$this->getId($idAssoc, 'catId', $row['catId'], null, 'representative_picture_id');
1918        if($representativeUrl!=null)
1919        {
1920          $imageNfo = new SrcImage(
1921                        array(
1922                          'id'=>$representativeUrl,
1923                          'path'=>$this->getId($idAssoc, 'imageId', $representativeUrl, '', 'path')
1924                        )
1925                      );
1926          $representativeUrl='./'.substr(DerivativeImage::url(IMG_THUMB, $imageNfo),strlen(PHPWG_ROOT_PATH));
1927        }
1928        else
1929        {
1930          $representativeUrl='';
1931        }
1932
1933
1934        $returned['rows'][]=array(
1935          $categoryNfo,
1936          $row['uaType'],
1937          sprintf('%d<span class="cPctCol">%0.2f%%</span>', $row['nbVisits'], 100*$row['nbVisits']/$result['total'][0]['nbVisits']),
1938          $representativeUrl
1939        );
1940      }
1941
1942      $returned['total']=array(
1943        '', '',
1944        isset($result['total'][0]['nbVisits'])?$result['total'][0]['nbVisits']:'0'
1945      );
1946
1947      $returned['nbItems']=$statFile->getStatCat(ASDF_GET_COUNT, 0, 0, $fields['rows'], $filter, array());
1948
1949      $statFile->close();
1950      return(json_encode($returned));
1951    }
1952
1953
1954
1955
1956
1957    /**
1958     * return the detail for images from a period
1959     *
1960     * @param String $period : the period to be processed
1961     *                          'allYear'    => process all year
1962     *                          'y-YYYY'     => process year YYYY
1963     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1964     * @param Array  $filterPost : filter options
1965     * @param Array  $sort: sort options
1966     * @param Array  $group: grouped items; could be:
1967     *                        'uaType'
1968     * @param Integer $pageNumber : page number to return
1969     * @return String : an array in json format
1970     *                    (Array)
1971     *                      'rows' => (Array)
1972     *                                  'category' => (String)
1973     *                                  'uaType' => (String)
1974     *                                  'nbVisits' => (Integer)
1975     *                      'total' => (Array)
1976     *                                  'category' => (String) [empty]
1977     *                                  'uaType' => (String) [empty]
1978     *                                  'nbVisits' => (Integer)
1979     *                      'nbItems' => (Integer)
1980     */
1981    protected function ajax_estat_admin_statImage($period, $filterPost, $sort, $group, $pageNumber, $nbItemsPage)
1982    {
1983      global $lang;
1984
1985      $year=null;
1986      $month=null;
1987
1988      $result=array(
1989        'rows'  => array(),
1990        'total' => array()
1991      );
1992      $returned=array(
1993        'rows'  => array(),
1994        'total' => array(),
1995        'nbItems' => 0
1996      );
1997      $fields=array(
1998        'rows' => array_diff(array('imageId', 'catId', 'uaType'), $group),
1999        'total' => array()
2000      );
2001      $filter=array();
2002
2003      if(substr($period,0,3)=='ym-')
2004      {
2005        $year=substr($period,3,4)*1;
2006        $month=substr($period,7,2)*1;
2007      }
2008      elseif(substr($period,0,2)=='y-')
2009      {
2010        $year=substr($period,2,4)*1;
2011      }
2012
2013      foreach($filterPost as $key => $val)
2014      {
2015        if($key==='additionalFilter')
2016        {
2017          if(isset($val['catId']))
2018            $filter['catId']=$this->buildCatIdFilter($val['catId']);
2019        }
2020        else
2021        {
2022          $filter[$val['id']]=$val;
2023        }
2024      }
2025
2026      if($year!=null)
2027        $filter['year']=array('operator' => '=', 'value' => $year);
2028      if($month!=null)
2029        $filter['month']=array('operator' => '=', 'value' => $month);
2030
2031      // open db file for the period
2032
2033
2034      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
2035
2036      $statFile->open(ASDF_OPEN_READ);
2037
2038      // get stats
2039      $result['rows']=$statFile->getStatImages(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
2040      $result['total']=$statFile->getStatImages(ASDF_GET_ROWS, 0, 0, array(), $filter, array());
2041
2042      // prepare categories&images properties
2043      $idList=new EStat_IdList(array('catId', 'imageId'));
2044      $idAssoc=array(
2045        'catId'=>array(),
2046        'imageId'=>array()
2047      );
2048
2049      // first, build category_id list
2050      foreach($result['rows'] as $row)
2051      {
2052        $idList->addItems(array('catId' => $row['catId']));
2053        $idList->addItems(array('imageId' => $row['imageId']));
2054      }
2055
2056      // get all needed properties for each category_id
2057      if(count($idList->getItems('catId')) > 0)
2058        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
2059
2060      if(count($idList->getItems('imageId')) > 0)
2061        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
2062
2063      foreach($result['rows'] as $row)
2064      {
2065        if(isset($row['uaType']))
2066        {
2067          $userAgentNfo=GPCUserAgent::getProperties(
2068              array(
2069                UA_DATA_BROWSER_TYPE => $row['uaType']
2070              )
2071            );
2072          $row['uaType']=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
2073        }
2074        else
2075        {
2076          $row['uaType']='';
2077        }
2078
2079        if($row['catId']==0)
2080        {
2081          $imageName=l10n('estat_special_category');
2082        }
2083        elseif($this->getId($idAssoc, 'catId', $row['catId'], '', 'name')=='')
2084        {
2085          $imageName=l10n('estat_deleted_category').' ['.$row['catId'].']';
2086        }
2087        else
2088        {
2089          $imageName='<a href="'.GPCCore::urlBuild('admin.album', array('categoryId'=>$row['catId'])).'">'.$this->getId($idAssoc, 'catId', $row['catId'], '', 'name').'</a>';
2090        }
2091        $imageName.=' / ';
2092
2093        $imageNfo=$this->getId($idAssoc, 'imageId', $row['imageId'], '', 'name');
2094        if($imageNfo!='')
2095        {
2096          $imageName.='<a href="'.GPCCore::urlBuild('admin.picture', array('pictureId'=>$row['imageId'])).'">'.$imageNfo.'</a>';
2097        }
2098        else
2099        {
2100          $imageName.=l10n('estat_deleted_image');
2101        }
2102
2103
2104        $imagePath=$this->getId($idAssoc, 'imageId', $row['imageId'], '', 'path');
2105        if($imagePath!='')
2106        {
2107          $imageNfo = new SrcImage(
2108                        array(
2109                          'id'=>$row['imageId'],
2110                          'path'=>$imagePath
2111                        )
2112                      );
2113          $imageUrl='./'.substr(DerivativeImage::url(IMG_THUMB, $imageNfo),strlen(PHPWG_ROOT_PATH));
2114        }
2115        else
2116        {
2117          $imageUrl='';
2118        }
2119
2120
2121        $returned['rows'][]=array(
2122          $imageName,
2123          $row['uaType'],
2124          sprintf('%d<span class="cPctCol">%0.2f%%</span>', $row['nbVisits'], 100*$row['nbVisits']/$result['total'][0]['nbVisits']),
2125          $imageUrl
2126        );
2127      }
2128
2129      $returned['total']=array(
2130        '', '',
2131        isset($result['total'][0]['nbVisits'])?$result['total'][0]['nbVisits']:'0'
2132      );
2133
2134      $returned['nbItems']=$statFile->getStatImages(ASDF_GET_COUNT, 0, 0, $fields['rows'], $filter, array());
2135
2136      $statFile->close();
2137      return(json_encode($returned));
2138    }
2139
2140
2141
2142
2143
2144
2145
2146    /**
2147     * Return a list of valid values for a given domain
2148     *
2149     * @param String $domain: domain of values
2150     * @return String: an array of values in json string
2151     *                  each values is an array('id'=>id, 'value'=>value)
2152     */
2153    protected function ajax_estat_admin_fctValidValues($domain, $filter)
2154    {
2155      $returned=array();
2156
2157      $id=-1;
2158      $idFilter=-1;
2159      switch($domain)
2160      {
2161        case 'uaBrowser':
2162          $id=UA_DATA_BROWSER;
2163          switch($filter)
2164          {
2165            case 'unknown':
2166              $idFilter=UA_BROWSER_TYPE_UNKNOWN;
2167              break;
2168            case 'crawler':
2169              $idFilter=UA_BROWSER_TYPE_CRAWLER;
2170              break;
2171            case 'computer':
2172              $idFilter=UA_BROWSER_TYPE_COMPUTER;
2173              break;
2174            case 'mobile':
2175              $idFilter=UA_BROWSER_TYPE_MOBILE;
2176              break;
2177            case 'console':
2178              $idFilter=UA_BROWSER_TYPE_CONSOLE;
2179              break;
2180          }
2181          break;
2182        case 'uaEngine':
2183          $id=UA_DATA_ENGINE;
2184          break;
2185        case 'uaOS':
2186          $id=UA_DATA_OS;
2187          switch($filter)
2188          {
2189            case 'unknown':
2190              $idFilter=UA_OS_TYPE_UNKNOWN;
2191              break;
2192            case 'linux':
2193              $idFilter=UA_OS_TYPE_LINUX;
2194              break;
2195            case 'bsd':
2196              $idFilter=UA_OS_TYPE_BSD;
2197              break;
2198            case 'unix':
2199              $idFilter=UA_OS_TYPE_UNIX;
2200              break;
2201            case 'windows':
2202              $idFilter=UA_OS_TYPE_WINDOWS;
2203              break;
2204            case 'OS2':
2205              $idFilter=UA_OS_TYPE_OS2;
2206              break;
2207          }
2208          break;
2209        case 'uaType':
2210          $id=UA_DATA_BROWSER_TYPE;
2211          break;
2212        case 'country':
2213          foreach($this->countryCodes as $countryCode)
2214          {
2215            $returned[]=array(
2216              'value' => $countryCode,
2217              'cols' => array(l10n('estat_country_'.$countryCode), "[$countryCode]")
2218            );
2219          }
2220          return(json_encode($returned));
2221          break;
2222      }
2223
2224
2225      foreach(GPCUserAgentValues::$UA_BrowserInfo[$id] as $key=>$value)
2226      {
2227        if($value[UA_PROP_NAME]=='Unknown') $value[UA_PROP_NAME]='ua_Unknown';
2228
2229        switch($domain)
2230        {
2231          case 'uaBrowser':
2232            if($idFilter==-1 or ($idFilter>-1 and $value[UA_PROP_TYPE]!=$idFilter))
2233                $returned[]=array(
2234                    'value' => $key,
2235                    'cols' => array(
2236                                l10n($value[UA_PROP_NAME]),
2237                                l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][$value[UA_PROP_TYPE]])
2238                              )
2239                  );
2240            break;
2241          case 'uaOS':
2242            if(GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_OS_TYPE][$value[UA_PROP_TYPE]]=='Unknown')
2243                GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_OS_TYPE][$value[UA_PROP_TYPE]]='ua_Unknown';
2244            if($idFilter==-1 or ($idFilter>-1 and $value[UA_PROP_TYPE]!=$idFilter))
2245                $returned[]=array(
2246                    'value' => $key,
2247                    'cols' => array(
2248                                l10n($value[UA_PROP_NAME]),
2249                                l10n(GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_OS_TYPE][$value[UA_PROP_TYPE]])
2250                              )
2251                  );
2252            break;
2253          case 'uaEngine':
2254            $returned[]=array(
2255                'value' => $key,
2256                'cols' => array(l10n($value[UA_PROP_NAME]))
2257              );
2258            break;
2259          case 'uaType':
2260            $returned[]=array(
2261                'value' => $key,
2262                'cols' => array(l10n('ua_'.$value))
2263              );
2264            break;
2265        }
2266      }
2267
2268      return(json_encode($returned));
2269    }
2270
2271
2272
2273    /**
2274     * retrieve all the availables periods in a tree list
2275     *
2276     * @return String: an array in a json string
2277     */
2278    private function ajax_estat_admin_statPeriodTreeList()
2279    {
2280      global $lang;
2281
2282      $returned=array(
2283        'items'=>array(
2284          0 => array(
2285            'id' => 'allYear',
2286            'name' => l10n('estat_allPeriods'),
2287            'nfo' => '',
2288            'level' => 0,
2289            'childs' => array()
2290          )
2291        )
2292      );
2293      $items=array();
2294
2295      $gStatFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
2296      $gStatFile->open(ASDF_OPEN_READ);
2297      $files=$gStatFile->getFilesList();
2298      $gStatFile->close();
2299
2300      foreach($files as $file)
2301      {
2302        if(!isset($items[$file['year']]))
2303          $items[$file['year']]=array(
2304              'id' => 'y-'.$file['year'],
2305              'name' => $file['year'],
2306              'nfo' => '',
2307              'level' => 0,
2308              'childs' => array()
2309            );
2310
2311        $items[$file['year']]['childs'][]=array(
2312              'id' => sprintf('ym-%04d%02d', $file['year'], $file['month']),
2313              'name' => $lang['month'][$file['month']],
2314              'nfo' => '',
2315              'level' => 1,
2316              'childs' => array()
2317            );
2318      }
2319
2320
2321
2322      foreach($items as $item)
2323      {
2324
2325        $returned['items'][]=$item;
2326      }
2327
2328      return(json_encode($returned));
2329    }
2330
2331
2332    /*
2333     * -------------------------------------------------------------------------
2334     * -- private functions
2335     * -------------------------------------------------------------------------
2336     */
2337
2338
2339  } //class EStat_Ajax
2340
2341  $returned=new EStat_Ajax($prefixeTable, __FILE__);
2342?>
Note: See TracBrowser for help on using the repository browser.