source: extensions/EStat/estat_ajax.php @ 30776

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

version 0.1.0b
. fix bug on thumb view
. fix SQLite compression managment & 'compress.method' config
. manage number of items per page by config

  • Property svn:executable set to *
File size: 78.4 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 and compression method is set, pack it
446        if($nbLogs<self::MAX_LOAD_LOG and $period!=date('Y-m') and $this->config['compress.method']=='gz')
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          if(isset($tmp[0]))
1154          {
1155            $returned['total']=array('', $tmp[0]['T'], $tmp[0]['C'], $tmp[0]['I'], $tmp[0]['A']);
1156          }
1157          else
1158          {
1159            $returned['total']=array('', '0', '0', '0', '0');
1160          }
1161          break;
1162        case 'y':
1163          foreach($result['rows'] as $year => $months)
1164          {
1165            foreach($months as $month => $values)
1166            {
1167              $returned['rows'][]=array(
1168                $lang['month'][$month],
1169                $values['T'],
1170                $values['C'],
1171                $values['I'],
1172                $values['A'],
1173                sprintf('%02d', $month)
1174              );
1175            }
1176          }
1177
1178          $tmp=$statFile->getStatPeriod(0, 0, $fields['total'], $filter, $sort);
1179          if(isset($tmp[0]))
1180          {
1181            $returned['total']=array('', $tmp[0][0]['T'], $tmp[0][0]['C'], $tmp[0][0]['I'], $tmp[0][0]['A']);
1182          }
1183          else
1184          {
1185            $returned['total']=array('', '0', '0', '0', '0');
1186          }
1187          break;
1188        default:
1189          // all years...
1190          foreach($result['rows'] as $year => $values)
1191          {
1192            if($year>0)
1193            {
1194              $returned['rows'][]=array(
1195                $year,
1196                $values[0]['T'],
1197                $values[0]['C'],
1198                $values[0]['I'],
1199                $values[0]['A'],
1200                sprintf('%02d', $year)
1201              );
1202            }
1203          }
1204          $tmp=$statFile->getStatPeriod(0, 0, $fields['total'], $filter, $sort);
1205          if(isset($tmp[0]))
1206          {
1207            $returned['total']=array('', $tmp[0][0]['T'], $tmp[0][0]['C'], $tmp[0][0]['I'], $tmp[0][0]['A']);
1208          }
1209          else
1210          {
1211            $returned['total']=array('', '0', '0', '0', '0');
1212          }
1213          break;
1214      }
1215
1216      $statFile->close();
1217      return(json_encode($returned));
1218    }
1219
1220
1221
1222
1223
1224    /**
1225     * return the number of visits from a period, formatted for a graph
1226     *
1227     * @param String $period : the period to be processed
1228     *                          'allYear'    => process all year
1229     *                          'y-YYYY'     => process year YYYY
1230     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1231     * @param Array  $filterPost : filter options
1232     * @param Integer $pageNumber : page number to return
1233     * @return String : an array in json format
1234     *                    (Array)
1235     *                      'axis' => (Array)  period as a formatted string
1236     *                      'series' => (Array) serie values
1237     *                      'maxValue' => (Integer) maximum value found on all series
1238     */
1239    protected function ajax_estat_admin_statPeriodGraph($period, $filterPost)
1240    {
1241      global $lang;
1242
1243      $periodType='';
1244      $year=null;
1245      $month=null;
1246
1247      $returned=array(
1248        'maxValue' => 0,
1249        'axis' => array(),
1250        'series' => array(
1251                      'viewedPages' => array(
1252                                      'name' => l10n('estat_viewedPages'),
1253                                      'nbVisits' => array()
1254                                    ),
1255                      'viewedAlbums' => array(
1256                                      'name' => l10n('estat_viewedAlbums'),
1257                                      'nbVisits' => array()
1258                                    ),
1259                      'viewedImages' => array(
1260                                      'name' => l10n('estat_viewedImages'),
1261                                      'nbVisits' => array()
1262                                    ),
1263                      'uniqueIP'  => array(
1264                                      'name' => l10n('estat_uniqueIP'),
1265                                      'nbVisits' => array()
1266                                    )
1267                    )
1268      );
1269
1270      $filter=array('uaData' => UA_DATA_BROWSER, 'catId' => array(), 'year'=>array(), 'month'=>array() );
1271      $fields=array();
1272
1273      if(substr($period,0,3)=='ym-')
1274      {
1275        $periodType='ym';
1276        $year=substr($period,3,4)*1;
1277        $month=substr($period,7,2)*1;
1278        $fields[]='day';
1279      }
1280      elseif(substr($period,0,2)=='y-')
1281      {
1282        $periodType='y';
1283        $fields[]='month';
1284        $year=substr($period,2,4)*1;
1285      }
1286      else // all other values assume $period=='allYear'
1287      {
1288        $fields[]='year';
1289      }
1290
1291      // filter on catId?
1292      if(isset($filterPost['catId']))
1293      {
1294        $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1295      }
1296      if($year)
1297        $filter['year']=array('operator' => '=', 'value' => $year);
1298      if($month)
1299        $filter['month']=array('operator' => '=', 'value' => $month);
1300
1301
1302      // open db file for the period
1303
1304      if($periodType=='ym')
1305      {
1306        $statFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
1307        $statFile->setPeriod($year, sprintf('%02d', $month));
1308      }
1309      else
1310      {
1311        $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1312      }
1313
1314
1315      $statFile->open(ASDF_OPEN_READ);
1316
1317      // get stats
1318      $result['rows']=$statFile->getStatPeriod(0, 0, $fields, $filter, null);
1319
1320
1321      // prepare data
1322      $axis=array();
1323      $series=array(
1324          'viewedPages' => array(),
1325          'viewedAlbums' => array(),
1326          'viewedImages' => array(),
1327          'uniqueIP' => array()
1328        );
1329
1330      switch($periodType)
1331      {
1332        case 'ym':
1333          foreach($result['rows'] as $day => $values)
1334          {
1335            if($returned['maxValue']<$values['T']) $returned['maxValue']=$values['T'];
1336            $returned['axis'][]=$day;
1337            $series['viewedPages'][$day]=$values['T'];
1338            $series['viewedAlbums'][$day]=$values['C'];
1339            $series['viewedImages'][$day]=$values['I'];
1340            $series['uniqueIP'][$day]=$values['A'];
1341          }
1342
1343          // format axis (add day letter for sunday)
1344          foreach($returned['axis'] as $key=>$day)
1345          {
1346            $period=$year.'-'.$month.'-'.$day;
1347            if(date('w', strtotime($period))==0) $returned['axis'][$key]=l10n('letter_day_sunday').' '.$day;
1348          }
1349          break;
1350        case 'y':
1351          foreach($result['rows'] as $year => $months)
1352          {
1353            foreach($months as $month => $values)
1354            {
1355              if($returned['maxValue']<$values['T']) $returned['maxValue']=$values['T'];
1356              $returned['axis'][]=$lang['month'][$month];
1357              $series['viewedPages'][$month]=$values['T'];
1358              $series['viewedAlbums'][$month]=$values['C'];
1359              $series['viewedImages'][$month]=$values['I'];
1360              $series['uniqueIP'][$month]=$values['A'];
1361            }
1362          }
1363          break;
1364        default:
1365          foreach($result['rows'] as $year => $values)
1366          {
1367            if($year>0)
1368            {
1369              if($returned['maxValue']<$values[0]['T']) $returned['maxValue']=$values[0]['T'];
1370              $returned['axis'][]=$year;
1371              $series['viewedPages'][$year]=$values[0]['T'];
1372              $series['viewedAlbums'][$year]=$values[0]['C'];
1373              $series['viewedImages'][$year]=$values[0]['I'];
1374              $series['uniqueIP'][$year]=$values[0]['A'];
1375            }
1376          }
1377          break;
1378      }
1379
1380      // format series values
1381      foreach($series as $serie=>$period)
1382      {
1383        foreach($period as $nbVisits)
1384        {
1385          $returned['series'][$serie]['nbVisits'][]=$nbVisits;
1386        }
1387      }
1388
1389      return(json_encode($returned));
1390    }
1391
1392
1393
1394
1395
1396    /**
1397     * return the detail for IP from a period
1398     *
1399     * @param String $period : the period to be processed
1400     *                          'allYear'    => process all year
1401     *                          'y-YYYY'     => process year YYYY
1402     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1403     * @param Array  $filterPost : filter options
1404     * @param Array  $sort: sort options
1405     * @param Array  $group: grouped items; could be:
1406     *                        'IPadress'
1407     *                        'country'
1408     *                        'uaType'
1409     * @param Integer $pageNumber : page number to return
1410     * @return String : an array in json format
1411     *                    (Array)
1412     *                      'rows' => (Array)
1413     *                                  'IPadress' => (String)
1414     *                                  'country' => (String)
1415     *                                  'uaType' => (String)
1416     *                                  'nbVisits' => (Integer)
1417     *                      'total' => (Array)
1418     *                                  'IPadress' => (String) [empty]
1419     *                                  'country' => (String) [empty]
1420     *                                  'uaType' => (String) [empty]
1421     *                                  'nbVisits' => (Integer)
1422     *                      'nbItems' => (Integer)
1423     */
1424    protected function ajax_estat_admin_statIP($period, $filterPost, $sort, $group, $pageNumber, $nbItemsPage)
1425    {
1426      global $lang;
1427
1428      $year=null;
1429      $month=null;
1430
1431      $result=array(
1432        'rows'  => array(),
1433        'total' => array()
1434      );
1435      $returned=array(
1436        'rows'  => array(),
1437        'total' => array(),
1438        'nbItems' => 0
1439      );
1440      $fields=array(
1441        'rows' => array_diff(array('uaType', 'IPadress', 'country'), $group),
1442        'total' => array()
1443      );
1444      $filter=array();
1445
1446      if(substr($period,0,3)=='ym-')
1447      {
1448        $year=substr($period,3,4)*1;
1449        $month=substr($period,7,2)*1;
1450      }
1451      elseif(substr($period,0,2)=='y-')
1452      {
1453        $year=substr($period,2,4)*1;
1454      }
1455
1456      foreach($filterPost as $key => $val)
1457      {
1458        if($key==='additionalFilter')
1459        {
1460          if(isset($val['catId']))
1461            $filter['catId']=$this->buildCatIdFilter($val['catId']);
1462        }
1463        else
1464        {
1465          $filter[$val['id']]=$val;
1466        }
1467      }
1468
1469      if($year!=null)
1470        $filter['year']=array('operator' => '=', 'value' => $year);
1471      if($month!=null)
1472        $filter['month']=array('operator' => '=', 'value' => $month);
1473
1474      // open db file for the period
1475
1476
1477      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1478
1479      $statFile->open(ASDF_OPEN_READ);
1480
1481      // get stats
1482      $result['rows']=$statFile->getStatIP(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
1483      $result['total']=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, array(), $filter, array());
1484
1485      foreach($result['rows'] as $row)
1486      {
1487        if(isset($row['uaType']))
1488        {
1489          $userAgentNfo=GPCUserAgent::getProperties(
1490              array(
1491                UA_DATA_BROWSER_TYPE => $row['uaType']
1492              )
1493            );
1494          $row['uaType']=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
1495        }
1496        else
1497        {
1498          $row['uaType']='';
1499        }
1500
1501        if(isset($row['country']))
1502        {
1503          $country='estat_country_'.strtoupper($row['country']);
1504          if(isset($lang[$country]))
1505          {
1506            $country="<span class='cCountryCode'>".$row['country'].'</span>'.$lang[$country];
1507          }
1508          else
1509          {
1510            $country="<span class='cCountryCode'>".$row['country'].'</span>';
1511          }
1512        }
1513        else
1514        {
1515          $country='';
1516          $row['country']='';
1517        }
1518
1519        if(isset($row['IPadress']))
1520        {
1521          if($row['country']!='--' and $row['country']!='XA')
1522          {
1523            $row['IPadress']='<a href="http://www.geoiptool.com/fr/?IP='.$row['IPadress'].'">'.$row['IPadress'].'</a>';
1524          }
1525        }
1526        else
1527        {
1528          $row['IPadress']='';
1529        }
1530
1531        $returned['rows'][]=array(
1532          $row['IPadress'],
1533          $country,
1534          $row['uaType'],
1535          sprintf('%d<span class="cPctCol">%0.2f%%</span>', $row['nbVisits'], 100*$row['nbVisits']/$result['total'][0]['nbVisits'])
1536        );
1537      }
1538
1539      $returned['total']=array(
1540        '', '', '',
1541        isset($result['total'][0]['nbVisits'])?$result['total'][0]['nbVisits']:'0'
1542      );
1543
1544      $returned['nbItems']=$statFile->getStatIP(ASDF_GET_COUNT, 0, 0, $fields['rows'], $filter, array());
1545
1546      $statFile->close();
1547      return(json_encode($returned));
1548    }
1549
1550
1551
1552    /**
1553     * return the detail needed to draw a GraphType for IP from a period
1554     *
1555     * @param String $period : the period to be processed
1556     *                          'allYear'    => process all year
1557     *                          'y-YYYY'     => process year YYYY
1558     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1559     * @param Array  $filterPost : filter options
1560     * @return String : an array in json format
1561     *                    (Array)
1562     *                      'values'       => (Array) (Integer)
1563     *                      'valuesLabels' => (Array) (String)
1564     */
1565    protected function ajax_estat_admin_statIPGraphType($period, $filterPost)
1566    {
1567      global $lang;
1568
1569      $year=null;
1570      $month=null;
1571
1572      $returned=array(
1573        'values' => array(0,0,0,0,0),
1574        'valuesLabels' => array(
1575            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_CRAWLER]),
1576            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_COMPUTER]),
1577            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_MOBILE]),
1578            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_CONSOLE]),
1579            l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][UA_BROWSER_TYPE_UNKNOWN])
1580        )
1581      );
1582      $fields=array('uaType');
1583
1584      $filter=array();
1585
1586      if(substr($period,0,3)=='ym-')
1587      {
1588        $year=substr($period,3,4)*1;
1589        $month=substr($period,7,2)*1;
1590      }
1591      elseif(substr($period,0,2)=='y-')
1592      {
1593        $year=substr($period,2,4)*1;
1594      }
1595
1596      if(isset($filterPost['catId']))
1597          $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1598
1599      if($year!=null)
1600        $filter['year']=array('operator' => '=', 'value' => $year);
1601      if($month!=null)
1602        $filter['month']=array('operator' => '=', 'value' => $month);
1603
1604      $sort=array(
1605        array('id'=>'uaType', 'direction'=>'A')
1606      );
1607
1608      // open db file for the period
1609      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1610
1611      $statFile->open(ASDF_OPEN_READ);
1612
1613      // get stats
1614      $result=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, $fields, $filter, $sort);
1615      $statFile->close();
1616
1617      $sum=0;
1618      foreach($result as $row)
1619      {
1620        switch($row['uaType'])
1621        {
1622          case UA_BROWSER_TYPE_CRAWLER:
1623            $key=0;
1624            break;
1625          case UA_BROWSER_TYPE_COMPUTER:
1626            $key=1;
1627            break;
1628          case UA_BROWSER_TYPE_MOBILE:
1629            $key=2;
1630            break;
1631          case UA_BROWSER_TYPE_CONSOLE:
1632            $key=3;
1633            break;
1634          case UA_BROWSER_TYPE_UNKNOWN:
1635            $key=4;
1636            break;
1637        }
1638
1639        $returned['values'][$key]=$row['nbVisits'];
1640        $sum+=$row['nbVisits'];
1641      }
1642
1643      foreach($returned['values'] as $key => $val)
1644      {
1645        if($val>0)
1646          $returned['valuesLabels'][$key].=sprintf(' (%0.2f%%)', 100*$val/$sum);
1647      }
1648
1649      return(json_encode($returned));
1650    }
1651
1652
1653
1654
1655
1656    /**
1657     * return the detail needed to draw a GraphCountry for IP from a period
1658     *
1659     * @param String $period : the period to be processed
1660     *                          'allYear'    => process all year
1661     *                          'y-YYYY'     => process year YYYY
1662     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1663     * @param Array  $filterPost : filter options
1664     * @return String : an array in json format
1665     *                    (Array)
1666     *                      'values'       => (Array) (Integer)
1667     *                      'valuesLabels' => (Array) (String)
1668     */
1669    protected function ajax_estat_admin_statIPGraphCountry($period, $filterPost)
1670    {
1671      global $lang;
1672
1673      $year=null;
1674      $month=null;
1675
1676      $returned=array(
1677        'values' => array(),
1678        'valuesLabels' => array()
1679      );
1680      $fields=array('country');
1681
1682      $filter=array();
1683
1684      if(substr($period,0,3)=='ym-')
1685      {
1686        $year=substr($period,3,4)*1;
1687        $month=substr($period,7,2)*1;
1688      }
1689      elseif(substr($period,0,2)=='y-')
1690      {
1691        $year=substr($period,2,4)*1;
1692      }
1693
1694      if(isset($filterPost['catId']))
1695          $filter['catId']=$this->buildCatIdFilter($filterPost['catId']);
1696
1697      if($year!=null)
1698        $filter['year']=array('operator' => '=', 'value' => $year);
1699      if($month!=null)
1700        $filter['month']=array('operator' => '=', 'value' => $month);
1701
1702      // open db file for the period
1703      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1704
1705      $statFile->open(ASDF_OPEN_READ);
1706
1707      // get stats
1708      $result=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, $fields, $filter);
1709      $statFile->close();
1710
1711      $sum=0;
1712      foreach($result as $row)
1713      {
1714        $sum+=$row['nbVisits'];
1715      }
1716
1717      $i=0;
1718      $nb=0;
1719      $other=-1;
1720      foreach($result as $row)
1721      {
1722        $pct=100*$row['nbVisits']/$sum;
1723
1724        if($i<9 and $pct>=0.5)
1725        {
1726          $country='estat_country_'.strtoupper($row['country']);
1727          if(isset($lang[$country]))
1728          {
1729            $country=$row['country'].' - '.$lang[$country];
1730          }
1731          else
1732          {
1733            $country=$row['country'];
1734          }
1735
1736          $country.=sprintf(' (%0.2f%%)', $pct);
1737
1738          $returned['values'][$i]=$row['nbVisits'];
1739          $returned['valuesLabels'][$i]=$country;
1740          $i++;
1741        }
1742        else
1743        {
1744          $nb++;
1745          $other=$i;
1746          if(!isset($returned['values'][$i]))
1747          {
1748            $returned['values'][$i]=0;
1749            $returned['valuesLabels'][$i]=l10n('estat_Other');
1750          }
1751          $returned['values'][$i]+=$row['nbVisits'];
1752        }
1753      }
1754
1755      if($other>-1)
1756      {
1757        $nbCountry=l10n('estat_country_nb');
1758        if($nb>1)
1759          $nbCountry=l10n('estat_countries_nb');
1760
1761        $returned['valuesLabels'][$other].=sprintf(' ('.$nbCountry.', %0.2f%%)', $nb, 100*$returned['values'][$other]/$sum );
1762      }
1763
1764      return(json_encode($returned));
1765    }
1766
1767
1768
1769
1770
1771    /**
1772     * return the detail for albums/categories from a period
1773     *
1774     * @param String $period : the period to be processed
1775     *                          'allYear'    => process all year
1776     *                          'y-YYYY'     => process year YYYY
1777     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1778     * @param Array  $filterPost : filter options
1779     * @param Array  $sort: sort options
1780     * @param Array  $group: grouped items; could be:
1781     *                        'uaType'
1782     * @param Integer $pageNumber : page number to return
1783     * @return String : an array in json format
1784     *                    (Array)
1785     *                      'rows' => (Array)
1786     *                                  'category' => (String)
1787     *                                  'uaType' => (String)
1788     *                                  'nbVisits' => (Integer)
1789     *                      'total' => (Array)
1790     *                                  'category' => (String) [empty]
1791     *                                  'uaType' => (String) [empty]
1792     *                                  'nbVisits' => (Integer)
1793     *                      'nbItems' => (Integer)
1794     */
1795    protected function ajax_estat_admin_statCategory($period, $filterPost, $sort, $group, $pageNumber, $nbItemsPage)
1796    {
1797      global $lang;
1798
1799      $year=null;
1800      $month=null;
1801
1802      $result=array(
1803        'rows'  => array(),
1804        'total' => array()
1805      );
1806      $returned=array(
1807        'rows'  => array(),
1808        'total' => array(),
1809        'nbItems' => 0
1810      );
1811      $fields=array(
1812        'rows' => array_diff(array('catId', 'uaType'), $group),
1813        'total' => array()
1814      );
1815      $filter=array();
1816
1817      if(substr($period,0,3)=='ym-')
1818      {
1819        $year=substr($period,3,4)*1;
1820        $month=substr($period,7,2)*1;
1821      }
1822      elseif(substr($period,0,2)=='y-')
1823      {
1824        $year=substr($period,2,4)*1;
1825      }
1826
1827      foreach($filterPost as $key => $val)
1828      {
1829        if($key==='additionalFilter')
1830        {
1831          if(isset($val['catId']))
1832            $filter['catId']=$this->buildCatIdFilter($val['catId']);
1833        }
1834        else
1835        {
1836          $filter[$val['id']]=$val;
1837        }
1838      }
1839
1840      if($year!=null)
1841        $filter['year']=array('operator' => '=', 'value' => $year);
1842      if($month!=null)
1843        $filter['month']=array('operator' => '=', 'value' => $month);
1844
1845      // open db file for the period
1846
1847
1848      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
1849
1850      $statFile->open(ASDF_OPEN_READ);
1851
1852      // get stats
1853      $result['rows']=$statFile->getStatCat(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
1854      $result['total']=$statFile->getStatCat(ASDF_GET_ROWS, 0, 0, array(), $filter, array());
1855
1856      // prepare categories&images properties
1857      $idList=new EStat_IdList(array('catId', 'imageId'));
1858      $idAssoc=array(
1859        'catId'=>array(),
1860        'imageId'=>array()
1861      );
1862
1863      // first, build category_id list
1864      foreach($result['rows'] as $row)
1865      {
1866        $idList->addItems(array('catId' => $row['catId']));
1867      }
1868
1869      // get upper categories and complete category_id list
1870      if(count($idList->getItems('catId')) > 0)
1871      {
1872        $sql="SELECT DISTINCT uppercats FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).");";
1873        $result2=pwg_query($sql);
1874        if($result2)
1875        {
1876          while($row=pwg_db_fetch_row($result2))
1877          {
1878            $ids=explode(',', $row[0]);
1879            foreach($ids as $id)
1880            {
1881              $idList->addItems(array('catId' => $id));
1882            }
1883          }
1884        }
1885      }
1886
1887      // get all needed properties for each category_id
1888      if(count($idList->getItems('catId')) > 0)
1889        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name, uppercats, representative_picture_id FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
1890
1891      // prepare image_id informations (for category representative picture)
1892      $categories=$idList->getItems('catId');
1893      foreach($idAssoc['catId'] as $category)
1894      {
1895        if($category['representative_picture_id']!=null)
1896          $idList->addItems(array('imageId' => $category['representative_picture_id']));
1897      }
1898
1899      if(count($idList->getItems('imageId')) > 0)
1900        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
1901
1902      foreach($result['rows'] as $row)
1903      {
1904        if(isset($row['uaType']))
1905        {
1906          $userAgentNfo=GPCUserAgent::getProperties(
1907              array(
1908                UA_DATA_BROWSER_TYPE => $row['uaType']
1909              )
1910            );
1911          $row['uaType']=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
1912        }
1913        else
1914        {
1915          $row['uaType']='';
1916        }
1917
1918
1919        if($row['catId']==0)
1920        {
1921          $categoryNfo=l10n('estat_special_category');
1922        }
1923        elseif($this->getId($idAssoc, 'catId', $row['catId'], '', 'name')=='')
1924        {
1925          $categoryNfo=l10n('estat_deleted_category');
1926        }
1927        else
1928        {
1929          $categoryNfo='<a href="'.GPCCore::urlBuild('admin.album', array('categoryId'=>$row['catId'])).'">'.$this->getId($idAssoc, 'catId', $row['catId'], '', 'name').'</a>';
1930        }
1931
1932        $uppercats=explode(',', $this->getId($idAssoc, 'catId', $row['catId'], null, 'uppercats'));
1933        if(count($uppercats)>1)
1934        {
1935          $categoryNfo=$this->getId($idAssoc, 'catId', $uppercats[count($uppercats)-2], '', 'name')." / ".$categoryNfo;
1936        }
1937
1938        $representativeUrl=$this->getId($idAssoc, 'catId', $row['catId'], null, 'representative_picture_id');
1939        if($representativeUrl!=null)
1940        {
1941          $imageNfo = new SrcImage(
1942                        array(
1943                          'id'=>$representativeUrl,
1944                          'path'=>$this->getId($idAssoc, 'imageId', $representativeUrl, '', 'path')
1945                        )
1946                      );
1947          $representativeUrl='./'.substr(DerivativeImage::url(IMG_THUMB, $imageNfo),strlen(PHPWG_ROOT_PATH));
1948        }
1949        else
1950        {
1951          $representativeUrl='';
1952        }
1953
1954
1955        $returned['rows'][]=array(
1956          $categoryNfo,
1957          $row['uaType'],
1958          sprintf('%d<span class="cPctCol">%0.2f%%</span>', $row['nbVisits'], 100*$row['nbVisits']/$result['total'][0]['nbVisits']),
1959          $representativeUrl
1960        );
1961      }
1962
1963      $returned['total']=array(
1964        '', '',
1965        isset($result['total'][0]['nbVisits'])?$result['total'][0]['nbVisits']:'0'
1966      );
1967
1968      $returned['nbItems']=$statFile->getStatCat(ASDF_GET_COUNT, 0, 0, $fields['rows'], $filter, array());
1969
1970      $statFile->close();
1971      return(json_encode($returned));
1972    }
1973
1974
1975
1976
1977
1978    /**
1979     * return the detail for images from a period
1980     *
1981     * @param String $period : the period to be processed
1982     *                          'allYear'    => process all year
1983     *                          'y-YYYY'     => process year YYYY
1984     *                          'ym-YYYYMM'  => process year/month YYYY/MM
1985     * @param Array  $filterPost : filter options
1986     * @param Array  $sort: sort options
1987     * @param Array  $group: grouped items; could be:
1988     *                        'uaType'
1989     * @param Integer $pageNumber : page number to return
1990     * @return String : an array in json format
1991     *                    (Array)
1992     *                      'rows' => (Array)
1993     *                                  'category' => (String)
1994     *                                  'uaType' => (String)
1995     *                                  'nbVisits' => (Integer)
1996     *                      'total' => (Array)
1997     *                                  'category' => (String) [empty]
1998     *                                  'uaType' => (String) [empty]
1999     *                                  'nbVisits' => (Integer)
2000     *                      'nbItems' => (Integer)
2001     */
2002    protected function ajax_estat_admin_statImage($period, $filterPost, $sort, $group, $pageNumber, $nbItemsPage)
2003    {
2004      global $lang;
2005
2006      $year=null;
2007      $month=null;
2008
2009      $result=array(
2010        'rows'  => array(),
2011        'total' => array()
2012      );
2013      $returned=array(
2014        'rows'  => array(),
2015        'total' => array(),
2016        'nbItems' => 0
2017      );
2018      $fields=array(
2019        'rows' => array_diff(array('imageId', 'catId', 'uaType'), $group),
2020        'total' => array()
2021      );
2022      $filter=array();
2023
2024      if(substr($period,0,3)=='ym-')
2025      {
2026        $year=substr($period,3,4)*1;
2027        $month=substr($period,7,2)*1;
2028      }
2029      elseif(substr($period,0,2)=='y-')
2030      {
2031        $year=substr($period,2,4)*1;
2032      }
2033
2034      foreach($filterPost as $key => $val)
2035      {
2036        if($key==='additionalFilter')
2037        {
2038          if(isset($val['catId']))
2039            $filter['catId']=$this->buildCatIdFilter($val['catId']);
2040        }
2041        else
2042        {
2043          $filter[$val['id']]=$val;
2044        }
2045      }
2046
2047      if($year!=null)
2048        $filter['year']=array('operator' => '=', 'value' => $year);
2049      if($month!=null)
2050        $filter['month']=array('operator' => '=', 'value' => $month);
2051
2052      // open db file for the period
2053
2054
2055      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
2056
2057      $statFile->open(ASDF_OPEN_READ);
2058
2059      // get stats
2060      $result['rows']=$statFile->getStatImages(ASDF_GET_ROWS, $pageNumber, $nbItemsPage, $fields['rows'], $filter, $sort);
2061      $result['total']=$statFile->getStatImages(ASDF_GET_ROWS, 0, 0, array(), $filter, array());
2062
2063      // prepare categories&images properties
2064      $idList=new EStat_IdList(array('catId', 'imageId'));
2065      $idAssoc=array(
2066        'catId'=>array(),
2067        'imageId'=>array()
2068      );
2069
2070      // first, build category_id list
2071      foreach($result['rows'] as $row)
2072      {
2073        $idList->addItems(array('catId' => $row['catId']));
2074        $idList->addItems(array('imageId' => $row['imageId']));
2075      }
2076
2077      // get all needed properties for each category_id
2078      if(count($idList->getItems('catId')) > 0)
2079        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
2080
2081      if(count($idList->getItems('imageId')) > 0)
2082        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
2083
2084      foreach($result['rows'] as $row)
2085      {
2086        if(isset($row['uaType']))
2087        {
2088          $userAgentNfo=GPCUserAgent::getProperties(
2089              array(
2090                UA_DATA_BROWSER_TYPE => $row['uaType']
2091              )
2092            );
2093          $row['uaType']=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
2094        }
2095        else
2096        {
2097          $row['uaType']='';
2098        }
2099
2100        if($row['catId']==0)
2101        {
2102          $imageName=l10n('estat_special_category');
2103        }
2104        elseif($this->getId($idAssoc, 'catId', $row['catId'], '', 'name')=='')
2105        {
2106          $imageName=l10n('estat_deleted_category').' ['.$row['catId'].']';
2107        }
2108        else
2109        {
2110          $imageName='<a href="'.GPCCore::urlBuild('admin.album', array('categoryId'=>$row['catId'])).'">'.$this->getId($idAssoc, 'catId', $row['catId'], '', 'name').'</a>';
2111        }
2112        $imageName.=' / ';
2113
2114        $imageNfo=$this->getId($idAssoc, 'imageId', $row['imageId'], '', 'name');
2115        if($imageNfo!='')
2116        {
2117          $imageName.='<a href="'.GPCCore::urlBuild('admin.picture', array('pictureId'=>$row['imageId'])).'">'.$imageNfo.'</a>';
2118        }
2119        else
2120        {
2121          $imageName.=l10n('estat_deleted_image');
2122        }
2123
2124
2125        $imagePath=$this->getId($idAssoc, 'imageId', $row['imageId'], '', 'path');
2126        if($imagePath!='')
2127        {
2128          $imageNfo = new SrcImage(
2129                        array(
2130                          'id'=>$row['imageId'],
2131                          'path'=>$imagePath
2132                        )
2133                      );
2134          $imageUrl='./'.substr(DerivativeImage::url(IMG_THUMB, $imageNfo),strlen(PHPWG_ROOT_PATH));
2135        }
2136        else
2137        {
2138          $imageUrl='';
2139        }
2140
2141
2142        $returned['rows'][]=array(
2143          $imageName,
2144          $row['uaType'],
2145          sprintf('%d<span class="cPctCol">%0.2f%%</span>', $row['nbVisits'], 100*$row['nbVisits']/$result['total'][0]['nbVisits']),
2146          $imageUrl
2147        );
2148      }
2149
2150      $returned['total']=array(
2151        '', '',
2152        isset($result['total'][0]['nbVisits'])?$result['total'][0]['nbVisits']:'0'
2153      );
2154
2155      $returned['nbItems']=$statFile->getStatImages(ASDF_GET_COUNT, 0, 0, $fields['rows'], $filter, array());
2156
2157      $statFile->close();
2158      return(json_encode($returned));
2159    }
2160
2161
2162
2163
2164
2165
2166
2167    /**
2168     * Return a list of valid values for a given domain
2169     *
2170     * @param String $domain: domain of values
2171     * @return String: an array of values in json string
2172     *                  each values is an array('id'=>id, 'value'=>value)
2173     */
2174    protected function ajax_estat_admin_fctValidValues($domain, $filter)
2175    {
2176      $returned=array();
2177
2178      $id=-1;
2179      $idFilter=-1;
2180      switch($domain)
2181      {
2182        case 'uaBrowser':
2183          $id=UA_DATA_BROWSER;
2184          switch($filter)
2185          {
2186            case 'unknown':
2187              $idFilter=UA_BROWSER_TYPE_UNKNOWN;
2188              break;
2189            case 'crawler':
2190              $idFilter=UA_BROWSER_TYPE_CRAWLER;
2191              break;
2192            case 'computer':
2193              $idFilter=UA_BROWSER_TYPE_COMPUTER;
2194              break;
2195            case 'mobile':
2196              $idFilter=UA_BROWSER_TYPE_MOBILE;
2197              break;
2198            case 'console':
2199              $idFilter=UA_BROWSER_TYPE_CONSOLE;
2200              break;
2201          }
2202          break;
2203        case 'uaEngine':
2204          $id=UA_DATA_ENGINE;
2205          break;
2206        case 'uaOS':
2207          $id=UA_DATA_OS;
2208          switch($filter)
2209          {
2210            case 'unknown':
2211              $idFilter=UA_OS_TYPE_UNKNOWN;
2212              break;
2213            case 'linux':
2214              $idFilter=UA_OS_TYPE_LINUX;
2215              break;
2216            case 'bsd':
2217              $idFilter=UA_OS_TYPE_BSD;
2218              break;
2219            case 'unix':
2220              $idFilter=UA_OS_TYPE_UNIX;
2221              break;
2222            case 'windows':
2223              $idFilter=UA_OS_TYPE_WINDOWS;
2224              break;
2225            case 'OS2':
2226              $idFilter=UA_OS_TYPE_OS2;
2227              break;
2228          }
2229          break;
2230        case 'uaType':
2231          $id=UA_DATA_BROWSER_TYPE;
2232          break;
2233        case 'country':
2234          foreach($this->countryCodes as $countryCode)
2235          {
2236            $returned[]=array(
2237              'value' => $countryCode,
2238              'cols' => array(l10n('estat_country_'.$countryCode), "[$countryCode]")
2239            );
2240          }
2241          return(json_encode($returned));
2242          break;
2243      }
2244
2245
2246      foreach(GPCUserAgentValues::$UA_BrowserInfo[$id] as $key=>$value)
2247      {
2248        if($value[UA_PROP_NAME]=='Unknown') $value[UA_PROP_NAME]='ua_Unknown';
2249
2250        switch($domain)
2251        {
2252          case 'uaBrowser':
2253            if($idFilter==-1 or ($idFilter>-1 and $value[UA_PROP_TYPE]!=$idFilter))
2254                $returned[]=array(
2255                    'value' => $key,
2256                    'cols' => array(
2257                                l10n($value[UA_PROP_NAME]),
2258                                l10n('ua_'.GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_BROWSER_TYPE][$value[UA_PROP_TYPE]])
2259                              )
2260                  );
2261            break;
2262          case 'uaOS':
2263            if(GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_OS_TYPE][$value[UA_PROP_TYPE]]=='Unknown')
2264                GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_OS_TYPE][$value[UA_PROP_TYPE]]='ua_Unknown';
2265            if($idFilter==-1 or ($idFilter>-1 and $value[UA_PROP_TYPE]!=$idFilter))
2266                $returned[]=array(
2267                    'value' => $key,
2268                    'cols' => array(
2269                                l10n($value[UA_PROP_NAME]),
2270                                l10n(GPCUserAgentValues::$UA_BrowserInfo[UA_DATA_OS_TYPE][$value[UA_PROP_TYPE]])
2271                              )
2272                  );
2273            break;
2274          case 'uaEngine':
2275            $returned[]=array(
2276                'value' => $key,
2277                'cols' => array(l10n($value[UA_PROP_NAME]))
2278              );
2279            break;
2280          case 'uaType':
2281            $returned[]=array(
2282                'value' => $key,
2283                'cols' => array(l10n('ua_'.$value))
2284              );
2285            break;
2286        }
2287      }
2288
2289      return(json_encode($returned));
2290    }
2291
2292
2293
2294    /**
2295     * retrieve all the availables periods in a tree list
2296     *
2297     * @return String: an array in a json string
2298     */
2299    private function ajax_estat_admin_statPeriodTreeList()
2300    {
2301      global $lang;
2302
2303      $returned=array(
2304        'items'=>array(
2305          0 => array(
2306            'id' => 'allYear',
2307            'name' => l10n('estat_allPeriods'),
2308            'nfo' => '',
2309            'level' => 0,
2310            'childs' => array()
2311          )
2312        )
2313      );
2314      $items=array();
2315
2316      $gStatFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
2317      $gStatFile->open(ASDF_OPEN_READ);
2318      $files=$gStatFile->getFilesList();
2319      $gStatFile->close();
2320
2321      foreach($files as $file)
2322      {
2323        if(!isset($items[$file['year']]))
2324          $items[$file['year']]=array(
2325              'id' => 'y-'.$file['year'],
2326              'name' => $file['year'],
2327              'nfo' => '',
2328              'level' => 0,
2329              'childs' => array()
2330            );
2331
2332        $items[$file['year']]['childs'][]=array(
2333              'id' => sprintf('ym-%04d%02d', $file['year'], $file['month']),
2334              'name' => $lang['month'][$file['month']],
2335              'nfo' => '',
2336              'level' => 1,
2337              'childs' => array()
2338            );
2339      }
2340
2341
2342
2343      foreach($items as $item)
2344      {
2345
2346        $returned['items'][]=$item;
2347      }
2348
2349      return(json_encode($returned));
2350    }
2351
2352
2353    /*
2354     * -------------------------------------------------------------------------
2355     * -- private functions
2356     * -------------------------------------------------------------------------
2357     */
2358
2359
2360  } //class EStat_Ajax
2361
2362  $returned=new EStat_Ajax($prefixeTable, __FILE__);
2363?>
Note: See TracBrowser for help on using the repository browser.