PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/class.xmoddlstats.inc

https://github.com/jcplat/console-seolan
PHP | 462 lines | 390 code | 31 blank | 41 comment | 51 complexity | 6b25a0a226ccb686a7f41be4fae66339 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. include 'add-ons/open-flash-chart2/php-ofc-library/open-flash-chart.php';
  3. /// Statistiques d'utilisation téléchargements
  4. class XModDLStats extends XModule {
  5. // conf open flash chart
  6. private $colours = array( '#004040', '#008000', '#FF0000', '#0000FF', '#00FF00',
  7. '#2CFFE7', '#FF5F20', '#742B0E', '#800080', '#FFFF00',
  8. '#C00000', '#00C0C0', '#580000', '#007A00', '#FFBB00',
  9. '#CF4812', '#78B753', '#8F6A32', '#F83496', '#A0A0A0');
  10. private $gridColour = '#E0E1E4';
  11. private $xcolor = '#cccccc';
  12. private $ycolor = '#ffffff';
  13. private $widgets = array(
  14. 'files' => 'Téléchargements (Mo)',
  15. );
  16. private $view_details = array (
  17. 'files',
  18. );
  19. function __construct($ar=NULL) {
  20. parent::__construct($ar);
  21. XLabels::loadLabels('xmoddlstats');
  22. if ($GLOBALS['LANG_USER'] == 'FR')
  23. setlocale( LC_TIME, 'fr_FR' );
  24. }
  25. // initialisation des proprietes
  26. //
  27. public function initOptions() {
  28. parent::initOptions();
  29. }
  30. /// securite des fonctions accessibles par le web
  31. function secGroups($function, $group=NULL) {
  32. $g=array(
  33. 'index' => array('ro','rw','rwv','admin'),
  34. 'clearStats' => array('admin'),
  35. 'trace' => array('none'),
  36. 'get_data' => array('r', 'rw', 'rwv', 'admin'),
  37. 'get_csv' => array('r', 'rw', 'rwv', 'admin'),
  38. );
  39. if(isset($g[$function])) {
  40. if(!empty($group)) return in_array($group, $g[$function]);
  41. return $g[$function];
  42. }
  43. return parent::secGroups($function,$group);
  44. }
  45. // cette fonction est appliquee pour afficher l'ensemble des methodes
  46. // de ce module
  47. //
  48. protected function _actionlist(&$my=NULL) {
  49. parent::_actionlist($my);
  50. $moid=$this->_moid;
  51. $o1=new XModuleAction($this, 'index', XLabels::getSysLabel('xmoddlstats','index','text'),
  52. '&moid='.$moid.'&_function=index&template=xmoddlstats/index.html&tplentry=br','display');
  53. // $o1->homepageable=$o1->menuable=$o1->quicklinkable=true;
  54. $o1->containable=true;
  55. $o1->setToolbar('general','browse');
  56. $my['index']=$o1;
  57. // $my['default']='index';
  58. if ($this->secure('', 'clearStats')) {
  59. $o1 = new XModuleAction($this, 'clearStats', XLabels::getSysLabel('xmoddlstats','clearstats','text'),
  60. '&moid='.$moid.'&_function=clearStats&template=xmoddlstats/index.html');
  61. $o1->homepageable=false;
  62. $o1->menuable=true;
  63. $o1->quicklinkable = false;
  64. $o1->needsconfirm = XLabels::getSysLabel('xmoddlstats','clearconfirm','text');
  65. $o1->group = 'edit';
  66. $my['clearStats'] = $o1;
  67. }
  68. }
  69. /// Action principale du menu
  70. public function getMainAction(){
  71. return $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'moid='.$this->_moid.'&function=index&template=xmoddlstats/index.html&tplentry=br';
  72. }
  73. // ajout d'une trace de download
  74. static function trace($userid, $moid, $file, $size) {
  75. $newkoid = XDataSource::getNewBasicOID('_DOWNLOADS');
  76. updateQuery("insert into _DOWNLOADS values ('$newkoid', '$userid', '$moid', '$file', $size, now(), now())");
  77. }
  78. // creation de la table (depuis wizard)
  79. static function createTasks() {
  80. if (XSystem::tableExists('_DOWNLOADS')) {
  81. return;
  82. }
  83. updateQuery('CREATE TABLE _DOWNLOADS (
  84. `KOID` varchar(40) NOT NULL default "",
  85. `USER` varchar(40),
  86. `SMOID` varchar(10) default NULL,
  87. `file` varchar(80) default NULL,
  88. `size` double default 0,
  89. `date` date default NULL,
  90. `time` time default NULL,
  91. PRIMARY KEY (`KOID`),
  92. KEY `USER` (`USER`(40)),
  93. KEY `SMOID` (`SMOID`),
  94. KEY `DATE_TIME` (`date`,`time`))');
  95. }
  96. // suppression des donnes pour un module
  97. //
  98. static function clean($moid=NULL, $user=NULL) {
  99. if (!XSystem::tableExists('_DOWNLOADS'))
  100. return false;
  101. if (!empty($moid))
  102. updateQuery('DELETE FROM _DOWNLOADS WHERE SMOID="'.$moid.'"');
  103. }
  104. // suppression de toutes les données
  105. //
  106. static function clearStats() {
  107. if (!XSystem::tableExists('_DOWNLOADS'))
  108. return false;
  109. updateQuery('DELETE FROM _DOWNLOADS');
  110. }
  111. function chk(&$message) {
  112. // suppression des donnees statistiques sur les modules supprimes
  113. $rs = selectQuery('select distinct MOID,SMOID from _DOWNLOADS LEFT OUTER JOIN MODULES ON MOID=SMOID WHERE ISNULL(MOID) and NOT SMOID="";');
  114. if (!empty($rs)) {
  115. while ($ors = $rs->fetch()) {
  116. updateQuery('DELETE FROM _DOWNLOADS WHERE SMOID="'.$ors['SMOID'].'"');
  117. $messge .= 'Deleted stats in _DOWNLOADS table for module '.$ors['SMOID'];
  118. }
  119. $rs->closeCursor();
  120. }
  121. }
  122. ///
  123. function index($ar) {
  124. $GLOBALS['XSHELL']->setTemplates('xmoddlstats/index.html');
  125. $this->get_interval();
  126. XShell::toScreen1('interval', $this->interval);
  127. $filter = array(
  128. 'mod' => $this->mod_list(),
  129. 'selected_mod' => '',
  130. 'user' => $this->user_list(),
  131. 'selected_user' => ''
  132. );
  133. foreach ($this->widgets as $widget => $title) {
  134. $func = "get_$widget";
  135. $data[] = $this->$func($title);
  136. $titles[] = $title;
  137. }
  138. XShell::toScreen1('filter', $filter);
  139. XShell::toScreen2('data', 'widget', $data);
  140. XShell::toScreen2('list', 'widget', array_keys($this->widgets));
  141. XShell::toScreen2('title', 'widget', $titles);
  142. XShell::toScreen2('view', 'details', $this->view_details);
  143. }
  144. function get_interval() {
  145. $p = new XParam(NULL, array(
  146. 'view' => 'week',
  147. 'ts' => time()
  148. ));
  149. // traitement période
  150. $ts = $p->get('ts');
  151. $view = $p->get('view');
  152. switch ($view) {
  153. case "week":
  154. $start_ts = mktime(0,0,0,date('m',$ts),1+date('d',$ts)-date('N',$ts),date('Y',$ts));
  155. $end_ts = $start_ts+ 6*60*60*24;
  156. $title = 'Semaine du ' . date('d/m/Y', $start_ts) . ' au ' . date('d/m/Y', $end_ts);
  157. $prev = $start_ts - 7*60*60*24;
  158. $next = $start_ts + 7*60*60*24;
  159. $start = date('Y-m-d', $start_ts);
  160. $end = date('Y-m-d', $next);
  161. break;
  162. case "month":
  163. $start_ts = mktime(0,0,0,date('m',$ts),1,date('Y',$ts));
  164. $title = 'Vue mensuelle '.utf8_encode( strftime('%B %Y', $start_ts));
  165. $prev = mktime(0,0,0,date('m',$ts)-1,1,date('Y',$ts));
  166. $next = mktime(0,0,0,date('m',$ts)+1,1,date('Y',$ts));
  167. $start = date('Y-m-d', $start_ts);
  168. $end_ts = $next-60*60*24;
  169. $end = date('Y-m-d', $end_ts);
  170. break;
  171. case "year":
  172. $start_ts = mktime(0,0,0,1,1,date('Y',$ts));
  173. $title = 'Vue annuelle '.strftime('%Y', $start_ts);
  174. $prev = mktime(0,0,0,1-12,1,date('Y',$ts));
  175. $next = mktime(0,0,0,1+12,1,date('Y',$ts));
  176. $start = date('Y-m-d', $start_ts);
  177. $end_ts = $next-60*60*24;
  178. $end = date('Y-m-d', $end_ts);
  179. break;
  180. }
  181. $this->interval = array('view' => $view, 'ts' => $ts, 'title' => $title, 'start_ts' => $start_ts, 'end_ts' => $end_ts, 'start' => $start, 'end' => $end, 'next' => $next, 'prev' => $prev);
  182. setSessionVar('interval', $this->interval);
  183. return $this->interval;
  184. }
  185. // filtre : liste des utilisateurs
  186. function user_list() {
  187. if (isset($this->users))
  188. return $this->users;
  189. $rs = selectQuery('select USER as koid, fullnam as nom from _DOWNLOADS join USERS on _DOWNLOADS.USER=USERS.KOID order by nom');
  190. $this->users[] = 'Utilisateur';
  191. while ($rs && $ors = $rs->fetch())
  192. $this->users[$ors['koid']] = $ors['nom'];
  193. return $this->users;
  194. }
  195. // filtre : liste des modules
  196. function mod_list() {
  197. if (isset($this->mod))
  198. return $this->mod;
  199. $rs = selectQuery('select distinct SMOID as koid, MODULE as nom from _DOWNLOADS join MODULES on _DOWNLOADS.SMOID=MODULES.MOID order by nom');
  200. $this->mod[] = 'Modules';
  201. while ($rs && $ors = $rs->fetch())
  202. $this->mod[$ors['koid']] = $ors['nom'];
  203. return $this->mod;
  204. }
  205. // ajax chart reload
  206. function get_data($ar) {
  207. $p = new XParam($ar);
  208. $this->interval = getSessionVar('interval');
  209. $target = $p->get('target');
  210. if (!empty($target)) {
  211. $func = "get_$target";
  212. echo $this->$func($this->widgets[$target]);
  213. }
  214. exit;
  215. }
  216. // ajax csv export
  217. function get_csv($ar) {
  218. $p = new XParam($ar);
  219. $this->interval = getSessionVar('interval');
  220. $target = $p->get('target');
  221. if (!empty($target)) {
  222. $func = "get_$target";
  223. echo $this->$func($target, 'csv');
  224. }
  225. exit;
  226. }
  227. function get_files($title, $format=null) {
  228. $p = new XParam();
  229. // traitement du filtre
  230. $user = $p->get('user');
  231. if (!empty($user))
  232. $where_clause .= " and _DOWNLOADS.USER='$user'";
  233. $byuser = $p->get('byuser');
  234. if (!empty($byuser) && empty($user)) { // repartition par user
  235. $join .= ' join USERS on _DOWNLOADS.USER=USERS.koid';
  236. $select_fields .= ', USERS.fullnam as user';
  237. $fields[] = 'user';
  238. }
  239. $mod = $p->get('mod');
  240. if (!empty($mod))
  241. $where_clause .= " and _DOWNLOADS.SMOID='$moid'";
  242. $bymod = $p->get('bymod');
  243. if (!empty($bymod) && empty($mod)) { // repartition par module
  244. $join .= ' join MODULES on _DOWNLOADS.SMOID=MODULES.moid';
  245. $select_fields .= ', MODULES.MODULE as module';
  246. $fields[] = 'module';
  247. }
  248. if (isset($fields))
  249. $groupby = implode(',', $fields).',';
  250. $query = "select round(sum(_DOWNLOADS.size)/1024/1024,2) as val, _DOWNLOADS.date as item $select_fields from _DOWNLOADS $join where '".$this->interval['start']."' <= _DOWNLOADS.date and _DOWNLOADS.date <= '".$this->interval['end']."' $where_clause group by $groupby item order by $groupby item";
  251. $data = $this->parse_query($query, $fields);
  252. if ($format == 'csv')
  253. return $this->evolution_CSV($data, $title, $fields);
  254. return $this->evolution_Chart($data, $title, $fields);
  255. }
  256. // format data to csv
  257. function repartition_CSV($query, $title, $fields=null) {
  258. $vals = '$values';
  259. foreach ($fields as $field)
  260. $vals .= '[$ors["'.$field.'"]]';
  261. $vals .= '[]';
  262. $rs = selectQuery($query);
  263. while ($rs && $ors = $rs->fetch()) {
  264. $items[] = $ors['item'];
  265. $data[] = $ors['val'];
  266. eval("$vals = {$ors['val']};");
  267. }
  268. header('Content-Type: text/csv;charset=ISO-8859-1');
  269. header('Content-Disposition: attachment;filename="'.$title.'_data.csv"');
  270. header('Cache-Control: max-age=0');
  271. if (!isset($fields)) {
  272. echo iconv("UTF-8", "ISO-8859-1", implode(';', $items));
  273. echo "\n".implode(';', $data)."\n";
  274. } else {
  275. foreach ($fields as $field)
  276. echo ';';
  277. echo iconv("UTF-8", "ISO-8859-1", $title);
  278. $this->render_CSV_lines($values);
  279. }
  280. exit;
  281. }
  282. // format data to csv
  283. function parse_query($query, $fields=null) {
  284. $vals = '$values';
  285. foreach ($fields as $field)
  286. $vals .= '[$ors["'.$field.'"]]';
  287. $init_vals = $vals;
  288. $vals .= '[$ors["item"]]';
  289. // init à 0 pour l'interval
  290. for ($ts = $this->interval['start_ts'], $i=0; $ts <= $this->interval['end_ts']; $ts += 60*60*24,$i++) {
  291. $emtpy_set[date('Y-m-d', $ts)] = 0;
  292. $items[] = date('d/m/y', $ts);
  293. $timestamps[] = $ts;
  294. }
  295. $rs = selectQuery($query);
  296. while ($rs && $ors = $rs->fetch()) {
  297. eval("if(!is_array($init_vals)) $init_vals = \$emtpy_set;");
  298. eval("$vals = {$ors['val']};");
  299. }
  300. return array('items' => $items, 'values' => $values, 'timestamps' => $timestamps);
  301. }
  302. // output a csv file from data
  303. function evolution_CSV(&$data, $title, $fields) {
  304. header('Content-Type: text/csv;charset=ISO-8859-1');
  305. header('Content-Disposition: attachment;filename="'.$title.'_data.csv"');
  306. header('Cache-Control: max-age=0');
  307. foreach ($fields as $field)
  308. echo ';';
  309. echo iconv("UTF-8", "ISO-8859-1", implode(';', $data['items']));
  310. if (!isset($fields))
  311. echo "\n".implode(';', $data['values'])."\n";
  312. else
  313. $this->render_CSV_lines($data['values']);
  314. exit;
  315. }
  316. // output a csv line
  317. function render_CSV_lines(&$values, $prefix='') {
  318. foreach ($values as $key => $val) {
  319. if (is_array($val)) {
  320. echo "\n".iconv("UTF-8", "ISO-8859-1", $prefix.$key).";";
  321. $this->render_CSV_lines($val, $prefix.';')."";
  322. } else
  323. echo "$val;";
  324. }
  325. }
  326. // bar repartition chart
  327. function repartition_Chart($query, $title, $fields=null) {
  328. // the chart
  329. $chart = new open_flash_chart();
  330. $chart->set_title( new title( $title ) );
  331. // initialiser à 5 valeurs pour éviter les déformations
  332. $labels = array_fill(0, 5, '');
  333. $bars = array_fill(0, 5, null);
  334. $i = 0;
  335. $rs = selectQuery($query);
  336. while ($rs && $ors = $rs->fetch()) {
  337. $val = (int)$ors['val'];
  338. $bar = new bar_value($val);
  339. $text = '';
  340. foreach ($fields as $field) {
  341. $text .= $ors[$field].' ';
  342. }
  343. $bar->set_tooltip( $text.'<br>#val#' );
  344. $bar->set_colour( $this->colours[$i % count($this->colours)] );
  345. $data[$i] = $bar;
  346. $labels[$i] = $text;
  347. $maxdata = $maxdata > $val ? $maxdata : $val;
  348. $i++;
  349. }
  350. $bar = new bar_cylinder();
  351. $bar->set_values( $data );
  352. $x_labels = new x_axis_labels();
  353. $x_labels->set_labels( $labels );
  354. $x_labels->rotate( -20 );
  355. $x_axis = new x_axis();
  356. $x_axis->set_labels($x_labels);
  357. $x_axis->set_3d( 2 );
  358. $x_axis->set_grid_colour( $this->gridColour );
  359. $x_axis->set_colour( $this->xcolor );
  360. $y_axis = new y_axis();
  361. $y_axis->set_range(0, max(10,ceil($maxdata/10)*10), 10);
  362. $y_axis->set_grid_colour( $this->gridColour );
  363. $y_axis->set_colour( $this->ycolor );
  364. $chart->add_element( $bar );
  365. $chart->set_bg_colour( '#FFFFFF' );
  366. $chart->set_x_axis($x_axis);
  367. $chart->set_y_axis($y_axis);
  368. return $chart->toPrettyString();
  369. }
  370. // line evolution chart
  371. function evolution_Chart($data, $title, $fields) {
  372. // the chart
  373. $chart = new open_flash_chart();
  374. $chart->set_title( new Title($title) );
  375. $chart->set_bg_colour( '#FFFFFF' );
  376. // Tooltip
  377. $tooltip = new tooltip();
  378. $tooltip->set_shadow( true );
  379. $tooltip->set_stroke( 1 );
  380. $chart->set_tooltip($tooltip);
  381. // x axis (step by hand, x_axis->steps is broken)
  382. foreach ($data['timestamps'] as $i => $ts) {
  383. if ($this->interval['view'] == 'week'
  384. || ($this->interval['view'] == 'month' && !($i%7)))
  385. $labels[] = strftime('%a %e', $ts);
  386. elseif ($this->interval['view'] == 'year'
  387. && (date('d', $ts) == '01' || date('d', $ts) == '15')) {
  388. $labels[] = utf8_encode(strftime('%d %b', $ts));
  389. $angle = -40;
  390. } else
  391. $labels[] = '';
  392. }
  393. $x_labels = new x_axis_labels();
  394. $x_labels->set_labels( $labels );
  395. $x_labels->rotate( $angle );
  396. $x_axis = new x_axis();
  397. $x_axis->set_labels($x_labels);
  398. $x_axis->set_grid_colour( $this->gridColour );
  399. $x_axis->set_colour( $this->xcolor );
  400. // $x_axis->steps(7);
  401. $chart->set_x_axis( $x_axis );
  402. $this->add_lines($data['values'], $chart, $maxdata);
  403. // y axis
  404. $y_axis = new y_axis();
  405. $y_axis->set_range(0, max(10,ceil($maxdata/10)*10), 10);
  406. $y_axis->set_grid_colour( $this->gridColour );
  407. $y_axis->set_colour( $this->ycolor );
  408. $chart->set_y_axis( $y_axis );
  409. return $chart->toPrettyString();
  410. }
  411. // add lines to evolution chart
  412. function add_lines(&$values, &$chart, &$maxdata, $i=0, $prefix=null) {
  413. if (!is_array(current($values))) {
  414. foreach ($values as $k => $value) {
  415. $dot = new hollow_dot($value);
  416. $dot->size(3)->halo_size(0);
  417. $dot->tooltip("$prefix $value");
  418. $line_values[] = $dot;
  419. $maxdata = $maxdata > $value ? $maxdata : $value;
  420. }
  421. $line = new line();
  422. $line->set_colour( $this->colours[$i % count($this->colours)] );
  423. $line->set_values( $line_values );
  424. // $line->set_key( $prefix, 10 );
  425. $chart->add_element( $line );
  426. } else
  427. foreach ($values as $key => $vals)
  428. $this->add_lines($vals, $chart, $maxdata, $i++, "$prefix $key<br>");
  429. }
  430. }
  431. ?>