source: extensions/EStat/estat_ajax_export.php @ 24058

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

version 0.1.0b

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

  • Property svn:executable set to *
File size: 43.7 KB
Line 
1<?php
2/*
3 * -----------------------------------------------------------------------------
4 * Plugin Name: EStat
5 * -----------------------------------------------------------------------------
6 * Author     : Grum
7 *   email    : grum@piwigo.org
8 *   website  : http://www.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 relative to file exports
18 *   => very similar to EStat_Ajax functions for the following services:
19 *          admin.export.history    <=>   admin.stat.history
20 *          admin.export.ip         <=>   admin.stat.ip
21 *          admin.export.category   <=>   admin.stat.category
22 *          admin.export.image      <=>   admin.stat.image
23 *
24 *   the admin.export.loadFile service is used to download produced files
25 * -----------------------------------------------------------------------------
26 */
27
28  // in this case, PHPWG_ROOT_PATH must be declared as an absolute path...
29  define('PHPWG_ROOT_PATH',dirname(dirname(dirname(__FILE__))).'/');
30  if(!defined('AJAX_CALL')) define('AJAX_CALL', true);
31
32  /*
33   * set ajax module in admin mode if request is used for admin interface
34   */
35  if(!isset($_REQUEST['ajaxfct'])) $_REQUEST['ajaxfct']='';
36  if(preg_match('/^admin\./i', $_REQUEST['ajaxfct'])) define('IN_ADMIN', true);
37
38  // the common.inc.php file loads all the main.inc.php plugins files
39  include_once(PHPWG_ROOT_PATH.'include/common.inc.php' );
40  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
41  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCUserAgent.class.inc.php');
42  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCExport.class.inc.php');
43  include_once('estat_root.class.inc.php');
44
45  load_language('plugin.lang', ESTAT_PATH);
46
47
48  class EStat_AjaxExport extends EStat_root
49  {
50    /**
51     * constructor
52     */
53    public function __construct($prefixeTable, $filelocation)
54    {
55      parent::__construct($prefixeTable, $filelocation);
56      $this->loadConfig();
57      $this->checkRequest();
58      $this->returnAjaxContent();
59    }
60
61    /**
62     * check the $_REQUEST values and set default values
63     *
64     */
65    protected function checkRequest()
66    {
67      global $user;
68
69      if(!isset($_REQUEST['errcode'])) $_REQUEST['errcode']='';
70      GPCAjax::checkToken();
71
72      // check if asked function is valid
73      if(!($_REQUEST[GPC_AJAX]=='admin.export.history' or
74           $_REQUEST[GPC_AJAX]=='admin.export.ip' or
75           $_REQUEST[GPC_AJAX]=='admin.export.category' or
76           $_REQUEST[GPC_AJAX]=='admin.export.image' or
77           $_REQUEST[GPC_AJAX]=='admin.export.loadFile'
78           )) $_REQUEST[GPC_AJAX]='';
79
80      if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']) and !is_admin()) $_REQUEST['ajaxfct']='';
81
82      if($_REQUEST[GPC_AJAX]!='')
83      {
84        // name, format & compression common to all requests
85        if(!isset($_REQUEST['name'])) $_REQUEST['name']='';
86        if(!isset($_REQUEST['format'])) $_REQUEST['format']='csv';
87        if(!isset($_REQUEST['compression'])) $_REQUEST['compression']='none';
88
89        if(!($_REQUEST['format']=='csv' or
90             $_REQUEST['format']=='ods' or
91             $_REQUEST['format']=='sqlite')) $_REQUEST['format']='csv';
92
93        if(!($_REQUEST['compression']=='none' or
94             $_REQUEST['compression']=='zip' or
95             $_REQUEST['compression']=='gz' or
96             $_REQUEST['compression']=='bz2')) $_REQUEST['format']='none';
97
98        if(preg_match('/^([a-z0-9\._]|-)+$/i', $_REQUEST['name'])!=1) $_REQUEST['name']='export_'.date('Ymd-His');
99
100        switch($_REQUEST[GPC_AJAX])
101        {
102          case 'admin.export.history':
103            if(!isset($_REQUEST['period'])) $_REQUEST['period']='';
104
105            if(!isset($_REQUEST['sort']))
106                $_REQUEST['sort']=array(
107                    array('direction' => 'A', 'id' => 'date')
108                );
109
110            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']=array();
111
112            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
113            break;
114          case 'admin.export.ip':
115            if(!isset($_REQUEST['period'])) $_REQUEST['period']='a';
116
117            if(!isset($_REQUEST['group'])) $_REQUEST['group']=array();
118
119            if(!isset($_REQUEST['sort']))
120                $_REQUEST['sort']=array(
121                    array('direction' => 'A', 'id' => 'ip')
122                );
123
124            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
125            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']=array();
126
127            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
128            $_REQUEST['filter']['additionalFilter']=$_REQUEST['additionalFilter'];
129            break;
130          case 'admin.export.category':
131          case 'admin.export.image':
132            if(!isset($_REQUEST['period'])) $_REQUEST['period']='a';
133
134            if(!isset($_REQUEST['group'])) $_REQUEST['group']=array();
135
136            if(!isset($_REQUEST['sort']))
137                $_REQUEST['sort']=array(
138                    array('direction' => 'A', 'id' => 'nbVisits')
139                );
140
141            if(!isset($_REQUEST['additionalFilter'])) $_REQUEST['additionalFilter']=array();
142            if(!isset($_REQUEST['filter'])) $_REQUEST['filter']=array();
143
144            if($_REQUEST['period']=='') $_REQUEST['ajaxfct']='';
145            $_REQUEST['filter']['additionalFilter']=$_REQUEST['additionalFilter'];
146            break;
147          case 'admin.export.loadFile':
148            break;
149          default:
150            $_REQUEST[GPC_AJAX]='';
151            break;
152        }
153
154      }
155    } //checkRequest
156
157
158    /**
159     * return ajax content
160     */
161    protected function returnAjaxContent()
162    {
163      $result="KO";
164      switch($_REQUEST[GPC_AJAX])
165      {
166        case 'admin.export.history':
167          $result=$this->ajax_estat_export_admin_statHistory($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['format'], $_REQUEST['compression'], $_REQUEST['name']);
168          break;
169        case 'admin.export.ip':
170          $result=$this->ajax_estat_export_admin_statIP($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['group'], $_REQUEST['format'], $_REQUEST['compression'], $_REQUEST['name']);
171          break;
172        case 'admin.export.category':
173          $result=$this->ajax_estat_export_admin_statCategory($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['group'], $_REQUEST['format'], $_REQUEST['compression'], $_REQUEST['name']);
174          break;
175        case 'admin.export.image':
176          $result=$this->ajax_estat_export_admin_statImage($_REQUEST['period'], $_REQUEST['filter'], $_REQUEST['sort'], $_REQUEST['group'], $_REQUEST['format'], $_REQUEST['compression'], $_REQUEST['name']);
177          break;
178        case 'admin.export.loadFile':
179          $result=$this->ajax_estat_export_admin_loadFile($_REQUEST['name']);
180          break;
181      }
182      if($result!='KO')
183      {
184        $result='OK:'.$this->getAdminLink('ajaxExport')."?ajaxfct=admin.export.loadFile&token=".get_pwg_token()."&name=".basename($result);
185      }
186      GPCAjax::returnResult($result);
187    }
188
189
190    /*------------------------------------------------------------------------*
191     *
192     * ADMIN FUNCTIONS
193     *
194     *----------------------------------------------------------------------- */
195
196    /**
197     * return the logs events from a period
198     *
199     * @param String $period : the period to be processed 'YYYYMM'
200     * @param Array  $filter : filter options
201     * @param Integer $pageNumber : page number to return
202     * @return String : an array in json format
203     *                    (Array) events properties
204     *                      'date' => (String) date time in 'YYYY-MM-DD HH:II:SS' format
205     *                      'IpUserId' => (String) IP or user login
206     *                      'country' => (String) country code (ISO 3366-1)
207     *                      'catId' => (String) name of the album
208     *                      'imageId' => (String) name of image
209     *                      'tags' => (String) tags list
210     *                      'section' => (String) section name
211     *                      'uaEngine' => (String) browser: engine+version
212     *                      'uaBrowser' => (String) browser name+version
213     *                      'uaOS' => (String) browser os: name+version
214     *                      'uaType' => (String) browser type: name
215     *                      'userAgent' => (String) user agent string
216     */
217    protected function ajax_estat_export_admin_statHistory($period, $filterPost, $sort, $format, $compression, $name)
218    {
219      global $lang;
220
221      $year=substr($period,0,4);
222      $month=substr($period,4,2);
223
224      $filter=array();
225      foreach($filterPost as $val)
226      {
227        $filter[$val['id']]=$val;
228      }
229
230      // open db file for the period
231      $monthStatFile=new StatDBMonth($this->fileStatDir, self::FILE_MONTH);
232      $monthStatFile->setPeriod($year, $month);
233      $monthStatFile->open(ASDF_OPEN_READ);
234
235      // get history & total number of items
236      $result=$monthStatFile->getLogs(ASDF_GET_ROWS, 0, 0, $filter, $sort);
237      $monthStatFile->close();
238
239      // prepare an EStat_IdList to buid a list of unique Id
240      $idList=new EStat_IdList(array('catId', 'imageId', 'tagsId', 'userId'));
241      // $idAssoc will get the label associated to the id
242      $idAssoc=array(
243        'catId'=>array(),
244        'imageId'=>array(),
245        'tagsId'=>array(),
246        'userId'=>array()
247      );
248
249      // build list of unique Id
250      foreach($result as $row)
251      {
252        $idList->addItems(
253          array(
254            'catId' => $row['catId'],
255            'imageId' => $row['imageId'],
256            'tagsId' => $row['tagsId'],
257            'userId' => $row['userId']
258          )
259        );
260      }
261
262
263      if(count($idList->getItems('catId')) > 0)
264        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
265
266      if(count($idList->getItems('imageId')) > 0)
267        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
268
269      if(count($idList->getItems('tagsId')) > 0)
270        $this->prepareIdList($idAssoc, 'tagsId', "SELECT id, name FROM ".TAGS_TABLE." WHERE id IN (".implode(',', $idList->getItems('tagsId')).") ORDER BY id;");
271
272      if(count($idList->getItems('userId')) > 0)
273        $this->prepareIdList($idAssoc, 'userId', "SELECT id, username AS name FROM ".USERS_TABLE." WHERE id IN (".implode(',', $idList->getItems('userId')).") ORDER BY id;");
274
275      $data=array();
276      // complete the data
277      foreach($result as $row)
278      {
279        $userAgentNfo=GPCUserAgent::getProperties(
280            array(
281              UA_DATA_BROWSER => $row['uaBrowser'],
282              UA_DATA_BROWSER_TYPE => $row['uaType'],
283              UA_DATA_OS => $row['uaOS'],
284              UA_DATA_ENGINE => $row['uaEngine']
285            )
286          );
287
288        if($userAgentNfo[UA_DATA_ENGINE_NAME]=='Unknown') $userAgentNfo[UA_DATA_ENGINE_NAME]='ua_Unknown';
289        if($userAgentNfo[UA_DATA_BROWSER_NAME]=='Unknown') $userAgentNfo[UA_DATA_BROWSER_NAME]='ua_Unknown';
290        if($userAgentNfo[UA_DATA_OS_NAME]=='Unknown') $userAgentNfo[UA_DATA_OS_NAME]='ua_Unknown';
291
292        $country=l10n('estat_country_'.strtoupper($row['country']));
293        if(isset($lang[$country]))
294        {
295          $country=$lang[$country];
296        }
297        else
298        {
299          $country='';
300        }
301
302        //$userAgent = UserAgent::parse($row['userAgent']);
303        $data[]=array(
304          'date' => date('Y-m-d H:i:s', $row['date']),
305          'IP' => $row['IPadress'],
306          'UserId' => $row['userId'],
307          'UserName' => $this->getId($idAssoc, 'userId', $row['userId'], '?', 'name'),
308          'countryId' => $row['country'],
309          'country' => $country,
310          'catId' => $row['catId'],
311          'catName' => GPCCore::getUserLanguageDesc($this->getId($idAssoc, 'catId', $row['catId'], ($row['catId']==0)?'-':'?')),
312          'imageId' => $row['imageId'],
313          'imageName' => $this->getId($idAssoc, 'imageId', $row['imageId'], ($row['imageId']==0)?'-':'?', 'name'),
314          'tags'  => $this->getId($idAssoc, 'tagsId', $row['tagsId'], '', 'name'),
315          'section' => l10n($row['section']),
316          'uaEngineId' => $row['uaEngine'],
317          'uaEngineName' => l10n($userAgentNfo[UA_DATA_ENGINE_NAME]),
318          'uaEngineVersion' => $row['uaEngineVersion'],
319          'uaBrowserId' => $row['uaBrowser'],
320          'uaBrowserName' => l10n($userAgentNfo[UA_DATA_BROWSER_NAME]),
321          'uaBrowserVersion' => $row['uaBrowserVersion'],
322          'uaOSId' => $row['uaOS'],
323          'uaOSName' => l10n($userAgentNfo[UA_DATA_OS_NAME]),
324          'uaOSVersion' => $row['uaOSVersion'],
325          'uaTypeId' => $row['uaType'],
326          'uaType' => l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]),
327          'userAgent' => $row['userAgent']
328        );
329      }
330
331
332      switch($format)
333      {
334        case 'csv':
335          $extension='.csv';
336          $export=new GPCCSVExport();
337          $export->setOptions(
338              array(
339                'separator' => $this->config['export.csv.separator'],
340                'decimalDot' => $this->config['export.csv.decimalDot'],
341                'useQuotes' => ($this->config['export.csv.useQuotes']=='y')?true:false,
342                'lineFeed' => $this->config['export.csv.lineFeed'],
343              )
344            );
345          $export->setColumnsDef(
346            array(
347              array('name' => l10n('estat_datetime')),
348              array('name' => l10n('estat_ipAdress')),
349              array('name' => l10n('estat_userId'), 'type' => 'INTEGER'),
350              array('name' => l10n('estat_userName')),
351              array('name' => l10n('estat_countryId')),
352              array('name' => l10n('estat_country')),
353              array('name' => l10n('estat_categoryId'), 'type' => 'INTEGER'),
354              array('name' => l10n('estat_category')),
355              array('name' => l10n('estat_imageId'), 'type' => 'INTEGER'),
356              array('name' => l10n('estat_image')),
357              array('name' => l10n('estat_tags')),
358              array('name' => l10n('estat_section')),
359              array('name' => l10n('estat_engineId'), 'type' => 'INTEGER'),
360              array('name' => l10n('estat_engine')),
361              array('name' => l10n('estat_engineVersion')),
362              array('name' => l10n('estat_browserId'), 'type' => 'INTEGER'),
363              array('name' => l10n('estat_browser')),
364              array('name' => l10n('estat_browserVersion')),
365              array('name' => l10n('estat_osId'), 'type' => 'INTEGER'),
366              array('name' => l10n('estat_os')),
367              array('name' => l10n('estat_osVersion')),
368              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
369              array('name' => l10n('estat_type')),
370              array('name' => l10n('estat_userAgentString'))
371            )
372          );
373          break;
374        case 'ods':
375          $extension='.ods';
376          $export=new GPCODSExport();
377          $export->setOptions(
378              array(
379                'sheetName' => l10n('estat_history'),
380                'fileTitle' => $this->config['export.ods.fileTitle'],
381                'fileSubject' => sprintf(l10n('estat_fileODSSubject'), l10n('estat_history')),
382                'keywords' => $this->config['export.ods.keywords'],
383                'comments' => sprintf(l10n('estat_fileODSComments_1'), date('Y-m-d@H:i:s'), ESTAT_VERSION, PHPWG_VERSION)
384              )
385            );
386          $export->setColumnsDef(
387            array(
388              array('name' => l10n('estat_datetime')),
389              array('name' => l10n('estat_ipAdress')),
390              array('name' => l10n('estat_userId'), 'type' => 'INTEGER'),
391              array('name' => l10n('estat_userName')),
392              array('name' => l10n('estat_countryId')),
393              array('name' => l10n('estat_country')),
394              array('name' => l10n('estat_categoryId'), 'type' => 'INTEGER'),
395              array('name' => l10n('estat_category')),
396              array('name' => l10n('estat_imageId'), 'type' => 'INTEGER'),
397              array('name' => l10n('estat_image')),
398              array('name' => l10n('estat_tags')),
399              array('name' => l10n('estat_section')),
400              array('name' => l10n('estat_engineId'), 'type' => 'INTEGER'),
401              array('name' => l10n('estat_engine')),
402              array('name' => l10n('estat_engineVersion')),
403              array('name' => l10n('estat_browserId'), 'type' => 'INTEGER'),
404              array('name' => l10n('estat_browser')),
405              array('name' => l10n('estat_browserVersion')),
406              array('name' => l10n('estat_osId'), 'type' => 'INTEGER'),
407              array('name' => l10n('estat_os')),
408              array('name' => l10n('estat_osVersion')),
409              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
410              array('name' => l10n('estat_type')),
411              array('name' => l10n('estat_userAgentString'))
412            )
413          );
414          break;
415        case 'sqlite':
416          $extension='.db';
417          $export=new GPCSQLiteExport();
418          $export->setOptions(
419              array(
420                'tableName' => 'history'
421              )
422            );
423          $export->setColumnsDef(
424            array(
425              array('name' => 'datetime'),
426              array('name' => 'ipAdress'),
427              array('name' => 'userId', 'type' => 'INTEGER'),
428              array('name' => 'userName'),
429              array('name' => 'countryId'),
430              array('name' => 'country'),
431              array('name' => 'categoryId', 'type' => 'INTEGER'),
432              array('name' => 'category'),
433              array('name' => 'imageId', 'type' => 'INTEGER'),
434              array('name' => 'image'),
435              array('name' => 'tags'),
436              array('name' => 'section'),
437              array('name' => 'engineId', 'type' => 'INTEGER'),
438              array('name' => 'engine'),
439              array('name' => 'engineVersion'),
440              array('name' => 'browserId', 'type' => 'INTEGER'),
441              array('name' => 'browser'),
442              array('name' => 'browserVersion'),
443              array('name' => 'osId', 'type' => 'INTEGER'),
444              array('name' => 'os'),
445              array('name' => 'osVersion'),
446              array('name' => 'typeId', 'type' => 'INTEGER'),
447              array('name' => 'type'),
448              array('name' => 'userAgentString')
449            )
450          );
451          break;
452      }
453      $export->setFileName($name.$extension);
454      $export->setFileDir($this->fileExportDir);
455
456      if($export->write($data))
457      {
458        $file=$this->fileExportDir.$export->getFileName();
459
460        if($compression!='none')
461        {
462          $compressedFile=$this->compress($file, $compression);
463          unlink($file);
464          $file=$compressedFile;
465        }
466        if(file_exists($file))
467        {
468          return($file);
469        }
470      }
471      return('KO');
472    }
473
474
475
476
477    /**
478     * return the detail for IP from a period
479     *
480     * @param String $period : the period to be processed
481     *                          'allYear'    => process all year
482     *                          'y-YYYY'     => process year YYYY
483     *                          'ym-YYYYMM'  => process year/month YYYY/MM
484     * @param Array  $filterPost : filter options
485     * @param Array  $sort: sort options
486     * @param Array  $group: grouped items; could be:
487     *                        'IPadress'
488     *                        'country'
489     *                        'uaType'
490     * @param Integer $pageNumber : page number to return
491     * @return String : an array in json format
492     *                    (Array)
493     *                      'rows' => (Array)
494     *                                  'IPadress' => (String)
495     *                                  'country' => (String)
496     *                                  'uaType' => (String)
497     *                                  'nbVisits' => (Integer)
498     *                      'total' => (Array)
499     *                                  'IPadress' => (String) [empty]
500     *                                  'country' => (String) [empty]
501     *                                  'uaType' => (String) [empty]
502     *                                  'nbVisits' => (Integer)
503     *                      'nbItems' => (Integer)
504     */
505    protected function ajax_estat_export_admin_statIP($period, $filterPost, $sort, $group, $format, $compression, $name)
506    {
507      global $lang;
508
509      $year=null;
510      $month=null;
511
512      $fields=array(
513        'rows' => array_diff(array('uaType', 'IPadress', 'country'), $group),
514        'total' => array()
515      );
516      $filter=array();
517
518      if(substr($period,0,3)=='ym-')
519      {
520        $year=substr($period,3,4)*1;
521        $month=substr($period,7,2)*1;
522      }
523      elseif(substr($period,0,2)=='y-')
524      {
525        $year=substr($period,2,4)*1;
526      }
527
528      foreach($filterPost as $key => $val)
529      {
530        if($key==='additionalFilter')
531        {
532          if(isset($val['catId']))
533            $filter['catId']=$this->buildCatIdFilter($val['catId']);
534        }
535        else
536        {
537          $filter[$val['id']]=$val;
538        }
539      }
540
541      if($year!=null)
542        $filter['year']=array('operator' => '=', 'value' => $year);
543      if($month!=null)
544        $filter['month']=array('operator' => '=', 'value' => $month);
545
546      // open db file for the period
547
548
549      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
550
551      $statFile->open(ASDF_OPEN_READ);
552
553      // get stats
554      $result=$statFile->getStatIP(ASDF_GET_ROWS, 0, 0, $fields['rows'], $filter, $sort);
555      $statFile->close();
556
557      $data=array();
558      foreach($result as $row)
559      {
560        if(isset($row['uaType']))
561        {
562          $userAgentNfo=GPCUserAgent::getProperties(
563              array(
564                UA_DATA_BROWSER_TYPE => $row['uaType']
565              )
566            );
567          $uaType=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
568        }
569        else
570        {
571          $row['uaType']='';
572          $uaType='';
573        }
574
575        if(isset($row['country']))
576        {
577          $country='estat_country_'.strtoupper($row['country']);
578          if(isset($lang[$country]))
579          {
580            $country=$lang[$country];
581          }
582          else
583          {
584            $country='';
585          }
586        }
587        else
588        {
589          $country='';
590          $row['country']='';
591        }
592
593        if(!isset($row['IPadress']))
594        {
595          $row['IPadress']='';
596        }
597
598        $data[]=array(
599          $row['IPadress'],
600          $row['country'],
601          $country,
602          $row['uaType'],
603          $uaType,
604          $row['nbVisits']
605        );
606      }
607
608
609
610      switch($format)
611      {
612        case 'csv':
613          $extension='.csv';
614          $export=new GPCCSVExport();
615          $export->setOptions(
616              array(
617                'separator' => $this->config['export.csv.separator'],
618                'decimalDot' => $this->config['export.csv.decimalDot'],
619                'useQuotes' => ($this->config['export.csv.useQuotes']=='y')?true:false,
620                'lineFeed' => $this->config['export.csv.lineFeed'],
621              )
622            );
623          $export->setColumnsDef(
624            array(
625              array('name' => l10n('estat_ipAdress')),
626              array('name' => l10n('estat_countryID')),
627              array('name' => l10n('estat_country')),
628              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
629              array('name' => l10n('estat_type')),
630              array('name' => l10n('estat_visits'), 'type' => 'INTEGER')
631            )
632          );
633          break;
634        case 'ods':
635          $extension='.ods';
636          $export=new GPCODSExport();
637          $export->setOptions(
638              array(
639                'sheetName' => l10n('estat_ipAdress'),
640                'fileTitle' => $this->config['export.ods.fileTitle'],
641                'fileSubject' => sprintf(l10n('estat_fileODSSubject'), l10n('estat_by_ip')),
642                'keywords' => $this->config['export.ods.keywords'],
643                'comments' => sprintf(l10n('estat_fileODSComments_1'), date('Y-m-d@H:i:s'), ESTAT_VERSION, PHPWG_VERSION)
644              )
645            );
646          $export->setColumnsDef(
647            array(
648              array('name' => l10n('estat_ipAdress')),
649              array('name' => l10n('estat_countryId')),
650              array('name' => l10n('estat_country')),
651              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
652              array('name' => l10n('estat_type')),
653              array('name' => l10n('estat_visits'), 'type' => 'INTEGER')
654            )
655          );
656          break;
657        case 'sqlite':
658          $extension='.db';
659          $export=new GPCSQLiteExport();
660          $export->setOptions(
661              array(
662                'tableName' => 'ipAdress'
663              )
664            );
665          $export->setColumnsDef(
666            array(
667              array('name' => 'ipAdress'),
668              array('name' => 'countryId'),
669              array('name' => 'country'),
670              array('name' => 'typeId', 'type' => 'INTEGER'),
671              array('name' => 'type'),
672              array('name' => 'visits', 'type' => 'INTEGER')
673            )
674          );
675          break;
676      }
677      $export->setFileName($name.$extension);
678      $export->setFileDir($this->fileExportDir);
679
680      if($export->write($data))
681      {
682        $file=$this->fileExportDir.$export->getFileName();
683
684        if($compression!='none')
685        {
686          $compressedFile=$this->compress($file, $compression);
687          unlink($file);
688          $file=$compressedFile;
689        }
690        if(file_exists($file))
691        {
692          return($file);
693        }
694      }
695      return('KO');
696    }
697
698
699
700
701    /**
702     * return the detail for albums/categories from a period
703     *
704     * @param String $period : the period to be processed
705     *                          'allYear'    => process all year
706     *                          'y-YYYY'     => process year YYYY
707     *                          'ym-YYYYMM'  => process year/month YYYY/MM
708     * @param Array  $filterPost : filter options
709     * @param Array  $sort: sort options
710     * @param Array  $group: grouped items; could be:
711     *                        'uaType'
712     * @return String : an array in json format
713     *                    (Array)
714     *                      'rows' => (Array)
715     *                                  'category' => (String)
716     *                                  'uaType' => (String)
717     *                                  'nbVisits' => (Integer)
718     *                      'total' => (Array)
719     *                                  'category' => (String) [empty]
720     *                                  'uaType' => (String) [empty]
721     *                                  'nbVisits' => (Integer)
722     *                      'nbItems' => (Integer)
723     */
724    protected function ajax_estat_export_admin_statCategory($period, $filterPost, $sort, $group, $format, $compression, $name)
725    {
726      global $lang;
727
728      $year=null;
729      $month=null;
730
731      $fields=array(
732        'rows' => array_diff(array('catId', 'uaType'), $group),
733        'total' => array()
734      );
735      $filter=array();
736
737      if(substr($period,0,3)=='ym-')
738      {
739        $year=substr($period,3,4)*1;
740        $month=substr($period,7,2)*1;
741      }
742      elseif(substr($period,0,2)=='y-')
743      {
744        $year=substr($period,2,4)*1;
745      }
746
747      foreach($filterPost as $key => $val)
748      {
749        if($key==='additionalFilter')
750        {
751          if(isset($val['catId']))
752            $filter['catId']=$this->buildCatIdFilter($val['catId']);
753        }
754        else
755        {
756          $filter[$val['id']]=$val;
757        }
758      }
759
760      if($year!=null)
761        $filter['year']=array('operator' => '=', 'value' => $year);
762      if($month!=null)
763        $filter['month']=array('operator' => '=', 'value' => $month);
764
765      // open db file for the period
766
767
768      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
769
770      $statFile->open(ASDF_OPEN_READ);
771
772      // get stats
773      $result=$statFile->getStatCat(ASDF_GET_ROWS, 0, 0, $fields['rows'], $filter, $sort);
774      $statFile->close();
775
776      // prepare categories&images properties
777      $idList=new EStat_IdList(array('catId', 'imageId'));
778      $idAssoc=array(
779        'catId'=>array(),
780        'imageId'=>array()
781      );
782
783      // first, build category_id list
784      foreach($result as $row)
785      {
786        $idList->addItems(array('catId' => $row['catId']));
787      }
788
789      // get all needed properties for each category_id
790      if(count($idList->getItems('catId')) > 0)
791        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
792
793      if(count($idList->getItems('imageId')) > 0)
794        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
795
796      $data=array();
797      foreach($result as $row)
798      {
799        if(isset($row['uaType']))
800        {
801          $userAgentNfo=GPCUserAgent::getProperties(
802              array(
803                UA_DATA_BROWSER_TYPE => $row['uaType']
804              )
805            );
806          $uaType=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
807        }
808        else
809        {
810          $row['uaType']='';
811          $uaType='';
812        }
813
814
815        if($row['catId']==0)
816        {
817          $categoryNfo=l10n('estat_special_category');
818        }
819        elseif($this->getId($idAssoc, 'catId', $row['catId'], '', 'name')=='')
820        {
821          $categoryNfo=l10n('estat_deleted_category');
822        }
823        else
824        {
825          $categoryNfo=$this->getId($idAssoc, 'catId', $row['catId'], '', 'name');
826        }
827
828        $data[]=array(
829          $row['catId'],
830          $categoryNfo,
831          $row['uaType'],
832          $uaType,
833          $row['nbVisits']
834        );
835      }
836
837
838
839      switch($format)
840      {
841        case 'csv':
842          $extension='.csv';
843          $export=new GPCCSVExport();
844          $export->setOptions(
845              array(
846                'separator' => $this->config['export.csv.separator'],
847                'decimalDot' => $this->config['export.csv.decimalDot'],
848                'useQuotes' => ($this->config['export.csv.useQuotes']=='y')?true:false,
849                'lineFeed' => $this->config['export.csv.lineFeed'],
850              )
851            );
852          $export->setColumnsDef(
853            array(
854              array('name' => l10n('estat_categoryId')),
855              array('name' => l10n('estat_category')),
856              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
857              array('name' => l10n('estat_type')),
858              array('name' => l10n('estat_visits'), 'type' => 'INTEGER')
859            )
860          );
861          break;
862        case 'ods':
863          $extension='.ods';
864          $export=new GPCODSExport();
865          $export->setOptions(
866              array(
867                'sheetName' => l10n('estat_category'),
868                'fileTitle' => $this->config['export.ods.fileTitle'],
869                'fileSubject' => sprintf(l10n('estat_fileODSSubject'), l10n('estat_by_category')),
870                'keywords' => $this->config['export.ods.keywords'],
871                'comments' => sprintf(l10n('estat_fileODSComments_1'), date('Y-m-d@H:i:s'), ESTAT_VERSION, PHPWG_VERSION)
872              )
873            );
874          $export->setColumnsDef(
875            array(
876              array('name' => l10n('estat_categoryId')),
877              array('name' => l10n('estat_category')),
878              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
879              array('name' => l10n('estat_type')),
880              array('name' => l10n('estat_visits'), 'type' => 'INTEGER')
881            )
882          );
883          break;
884        case 'sqlite':
885          $extension='.db';
886          $export=new GPCSQLiteExport();
887          $export->setOptions(
888              array(
889                'tableName' => 'album'
890              )
891            );
892          $export->setColumnsDef(
893            array(
894              array('name' => 'albumId'),
895              array('name' => 'album'),
896              array('name' => 'typeId', 'type' => 'INTEGER'),
897              array('name' => 'type'),
898              array('name' => 'visits', 'type' => 'INTEGER')
899            )
900          );
901          break;
902      }
903      $export->setFileName($name.$extension);
904      $export->setFileDir($this->fileExportDir);
905
906      if($export->write($data))
907      {
908        $file=$this->fileExportDir.$export->getFileName();
909
910        if($compression!='none')
911        {
912          $compressedFile=$this->compress($file, $compression);
913          unlink($file);
914          $file=$compressedFile;
915        }
916        if(file_exists($file))
917        {
918          return($file);
919        }
920      }
921      return('KO');
922    }
923
924
925
926
927
928    /**
929     * return the detail for images from a period
930     *
931     * @param String $period : the period to be processed
932     *                          'allYear'    => process all year
933     *                          'y-YYYY'     => process year YYYY
934     *                          'ym-YYYYMM'  => process year/month YYYY/MM
935     * @param Array  $filterPost : filter options
936     * @param Array  $sort: sort options
937     * @param Array  $group: grouped items; could be:
938     *                        'uaType'
939     * @param Integer $pageNumber : page number to return
940     * @return String : an array in json format
941     *                    (Array)
942     *                      'rows' => (Array)
943     *                                  'category' => (String)
944     *                                  'uaType' => (String)
945     *                                  'nbVisits' => (Integer)
946     *                      'total' => (Array)
947     *                                  'category' => (String) [empty]
948     *                                  'uaType' => (String) [empty]
949     *                                  'nbVisits' => (Integer)
950     *                      'nbItems' => (Integer)
951     */
952    protected function ajax_estat_export_admin_statImage($period, $filterPost, $sort, $group, $format, $compression, $name)
953    {
954      global $lang;
955
956      $year=null;
957      $month=null;
958
959      $fields=array(
960        'rows' => array_diff(array('imageId', 'catId', 'uaType'), $group),
961        'total' => array()
962      );
963      $filter=array();
964
965      if(substr($period,0,3)=='ym-')
966      {
967        $year=substr($period,3,4)*1;
968        $month=substr($period,7,2)*1;
969      }
970      elseif(substr($period,0,2)=='y-')
971      {
972        $year=substr($period,2,4)*1;
973      }
974
975      foreach($filterPost as $key => $val)
976      {
977        if($key==='additionalFilter')
978        {
979          if(isset($val['catId']))
980            $filter['catId']=$this->buildCatIdFilter($val['catId']);
981        }
982        else
983        {
984          $filter[$val['id']]=$val;
985        }
986      }
987
988      if($year!=null)
989        $filter['year']=array('operator' => '=', 'value' => $year);
990      if($month!=null)
991        $filter['month']=array('operator' => '=', 'value' => $month);
992
993      // open db file for the period
994      $statFile=new StatDBGlobal($this->fileStatDir, self::FILE_GLOBAL);
995      $statFile->open(ASDF_OPEN_READ);
996
997      // get stats
998      $result=$statFile->getStatImages(ASDF_GET_ROWS, 0, 0, $fields['rows'], $filter, $sort);
999      $statFile->close();
1000
1001      // prepare categories&images properties
1002      $idList=new EStat_IdList(array('catId', 'imageId'));
1003      $idAssoc=array(
1004        'catId'=>array(),
1005        'imageId'=>array()
1006      );
1007
1008      // first, build category_id list
1009      foreach($result as $row)
1010      {
1011        $idList->addItems(array('catId' => $row['catId']));
1012        $idList->addItems(array('imageId' => $row['imageId']));
1013      }
1014
1015      // get all needed properties for each category_id
1016      if(count($idList->getItems('catId')) > 0)
1017        $this->prepareIdList($idAssoc, 'catId', "SELECT id, name FROM ".CATEGORIES_TABLE." WHERE id IN (".implode(',', $idList->getItems('catId')).") ORDER BY id;");
1018
1019      if(count($idList->getItems('imageId')) > 0)
1020        $this->prepareIdList($idAssoc, 'imageId', "SELECT id, file AS name, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(',', $idList->getItems('imageId')).") ORDER BY id;");
1021
1022      $data=array();
1023      foreach($result as $row)
1024      {
1025        if(isset($row['uaType']))
1026        {
1027          $userAgentNfo=GPCUserAgent::getProperties(
1028              array(
1029                UA_DATA_BROWSER_TYPE => $row['uaType']
1030              )
1031            );
1032          $uaType=l10n('ua_'.$userAgentNfo[UA_DATA_BROWSER_TYPE_NAME]);
1033        }
1034        else
1035        {
1036          $row['uaType']='';
1037          $uaType='';
1038        }
1039
1040        if($row['catId']==0)
1041        {
1042          $catName=l10n('estat_special_category');
1043        }
1044        elseif($this->getId($idAssoc, 'catId', $row['catId'], '', 'name')=='')
1045        {
1046          $catName=l10n('estat_deleted_category').' ['.$row['catId'].']';
1047        }
1048        else
1049        {
1050          $catName=$this->getId($idAssoc, 'catId', $row['catId'], '', 'name');
1051        }
1052
1053        $imageNfo=$this->getId($idAssoc, 'imageId', $row['imageId'], '', 'name');
1054        if($imageNfo!='')
1055        {
1056          $imageName=$imageNfo;
1057        }
1058        else
1059        {
1060          $imageName=l10n('estat_deleted_image');
1061        }
1062
1063
1064        $data[]=array(
1065          $row['catId'],
1066          $catName,
1067          $row['imageId'],
1068          $imageName,
1069          $row['uaType'],
1070          $uaType,
1071          $row['nbVisits']
1072        );
1073      }
1074
1075
1076
1077      switch($format)
1078      {
1079        case 'csv':
1080          $extension='.csv';
1081          $export=new GPCCSVExport();
1082          $export->setOptions(
1083              array(
1084                'separator' => $this->config['export.csv.separator'],
1085                'decimalDot' => $this->config['export.csv.decimalDot'],
1086                'useQuotes' => ($this->config['export.csv.useQuotes']=='y')?true:false,
1087                'lineFeed' => $this->config['export.csv.lineFeed'],
1088              )
1089            );
1090          $export->setColumnsDef(
1091            array(
1092              array('name' => l10n('estat_categoryId')),
1093              array('name' => l10n('estat_category')),
1094              array('name' => l10n('estat_imageId')),
1095              array('name' => l10n('estat_image')),
1096              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
1097              array('name' => l10n('estat_type')),
1098              array('name' => l10n('estat_visits'), 'type' => 'INTEGER')
1099            )
1100          );
1101          break;
1102        case 'ods':
1103          $extension='.ods';
1104          $export=new GPCODSExport();
1105          $export->setOptions(
1106              array(
1107                'sheetName' => l10n('estat_image'),
1108                'fileTitle' => $this->config['export.ods.fileTitle'],
1109                'fileSubject' => sprintf(l10n('estat_fileODSSubject'), l10n('estat_by_image')),
1110                'keywords' => $this->config['export.ods.keywords'],
1111                'comments' => sprintf(l10n('estat_fileODSComments_1'), date('Y-m-d@H:i:s'), ESTAT_VERSION, PHPWG_VERSION)
1112              )
1113            );
1114          $export->setColumnsDef(
1115            array(
1116              array('name' => l10n('estat_categoryId')),
1117              array('name' => l10n('estat_category')),
1118              array('name' => l10n('estat_imageId')),
1119              array('name' => l10n('estat_image')),
1120              array('name' => l10n('estat_typeId'), 'type' => 'INTEGER'),
1121              array('name' => l10n('estat_type')),
1122              array('name' => l10n('estat_visits'), 'type' => 'INTEGER')
1123            )
1124          );
1125          break;
1126        case 'sqlite':
1127          $extension='.db';
1128          $export=new GPCSQLiteExport();
1129          $export->setOptions(
1130              array(
1131                'tableName' => 'image'
1132              )
1133            );
1134          $export->setColumnsDef(
1135            array(
1136              array('name' => 'albumId'),
1137              array('name' => 'album'),
1138              array('name' => 'imageId'),
1139              array('name' => 'image'),
1140              array('name' => 'typeId', 'type' => 'INTEGER'),
1141              array('name' => 'type'),
1142              array('name' => 'visits', 'type' => 'INTEGER')
1143            )
1144          );
1145          break;
1146      }
1147      $export->setFileName($name.$extension);
1148      $export->setFileDir($this->fileExportDir);
1149
1150      if($export->write($data))
1151      {
1152        $file=$this->fileExportDir.$export->getFileName();
1153
1154        if($compression!='none')
1155        {
1156          $compressedFile=$this->compress($file, $compression);
1157          unlink($file);
1158          $file=$compressedFile;
1159        }
1160        if(file_exists($file))
1161        {
1162          return($file);
1163        }
1164      }
1165      return('KO');
1166    }
1167
1168
1169    /**
1170     * used for file download
1171     * stop the script and returns the file content
1172     *
1173     * @param String $name: file to upload
1174     * @param Booelan $deleteFile: is true, given file is deleted after content is returned
1175     * @return String: the file content with http header
1176     */
1177    private function ajax_estat_export_admin_loadFile($name, $deleteFile=true)
1178    {
1179      $file=$this->fileExportDir.$name;
1180      if(!file_exists($file))
1181        do_error(404, "Requested file not readable - $name");
1182
1183      $gmtMtime=gmdate('D, d M Y H:i:s', filemtime($file)).' GMT';
1184
1185      $infos=pathinfo($file, PATHINFO_EXTENSION);
1186
1187      switch($infos)
1188      {
1189        case 'csv':
1190          $mimeType='text/csv';
1191          break;
1192        case 'ods':
1193          $mimeType='application/vnd.oasis.opendocument.spreadsheet';
1194          break;
1195        case 'db';
1196          $mimeType='application/octet-stream';
1197          break;
1198        case 'gz':
1199          $mimeType='application/gzip';
1200          break;
1201        case 'bz2':
1202          $mimeType='application/zip';
1203          break;
1204        case 'zip':
1205          $mimeType='application/zip';
1206          break;
1207        default:
1208          $mimeType='application/octet-stream';
1209          break;
1210      }
1211
1212      $httpHeaders=array(
1213          'Content-Length: '.@filesize($file),
1214          'Last-Modified: '.$gmtMtime,
1215          'Content-Type: '.$mimeType,
1216          'Content-Disposition: attachment; filename="'.basename($file).'";',
1217          'Content-Transfer-Encoding: binary',
1218        );
1219
1220      foreach ($httpHeaders as $header)
1221      {
1222        header($header);
1223      }
1224
1225      $content=@readfile($file);
1226      if($deleteFile) unlink($file);
1227      die($content);
1228    } // ajax_estat_export_admin_loadFile
1229
1230
1231    /* ------------------------------------------------------------------------------------------------
1232       -- private method
1233       ------------------------------------------------------------------------------------------------ */
1234
1235    /**
1236     * compress the file, according to the asked method
1237     * the file will be compressed in the same directory than the source file
1238     *
1239     * @param String $file: file to compress
1240     * @return String: compressed file name, or empty string if something wrong
1241     */
1242    private function compress($file, $method)
1243    {
1244      if(!file_exists($file)) return('');
1245      $infos=pathinfo($file);
1246
1247      switch($method)
1248      {
1249        case 'zip':
1250          $compressedFile=$infos['dirname'].'/'.basename($infos['basename'], '.'.$infos['extension']).'.zip';
1251          if(GPCCompress::zip($file, $compressedFile, '', $infos['dirname']))
1252            return($compressedFile);
1253          break;
1254        case 'gz':
1255          $compressedFile=$file.'.gz';
1256          if(GPCCompress::gzip($file, $compressedFile))
1257            return($compressedFile);
1258          break;
1259        case 'bz2':
1260          $compressedFile=$file.'.bz2';
1261          if(GPCCompress::bzip2($file, $compressedFile))
1262            return($compressedFile);
1263          break;
1264      }
1265      return('');
1266    } //compress
1267
1268  } //class EStat_AjaxExport
1269
1270
1271
1272
1273
1274
1275  $returned=new EStat_AjaxExport($prefixeTable, __FILE__);
1276?>
Note: See TracBrowser for help on using the repository browser.