'plot','condition'=>'mining', 'download'=>'print','statistic'=>'statistics', 'getparameter'=>'ws_print', 'getdataset' => 'ws_print', 'getorbites' => 'ws_print', 'getplot' => 'ws_plot'); public function __construct($user, $year = NULL) { if (!is_dir(DATAPATH.'Statistics')) { if (!mkdir(DATAPATH.'Statistics', 0775)) $this->success = false; //return -1; if (!chgrp(DATAPATH.'Statistics', APACHE_USER)) $this->success = false; // return -1; } $this->statsFilePath = $this->getStatsFilePath($user, $year); } public function addTask($user, $task, $vars) { $this->concurrentAccessGuestFile(array($this,'_addTask'),array('user' => $user, 'task' => $task, 'vars' => $vars)); } public function getModulesStat($start, $stop, $update) { return $this->concurrentAccessGuestFile(array($this,'_getModulesStat'), array('start' => $start, 'stop' => $stop, 'update' => $update)); } public function mergeXml($year) { return $this->concurrentAccessGuestFile(array($this,'_mergeXml'), array('year' => $year)); } public function getDataStat($index, $start, $stop, $update) { return $this->concurrentAccessGuestFile(array($this,'_getDataStat'), array('index' => $index, 'start', $start, 'stop' => $stop, 'update' => $update)); } public function mergeStats($inXml) { return $this->concurrentAccessGuestFile(array($this,'_mergeStats'), array('inXml' => $inXml)); } private function getStatsFilePath($user, $year) { if (!isset($year)) $thisYear = date("Y"); else $thisYear = $year; if (empty($user)){ return DATAPATH."Statistics/Stats$thisYear.xml"; } return USERPATH.$user."/Stats$thisYear.xml"; } private function concurrentAccessGuestFile($callback, $options) { $lockFile = $this->statsFilePath.".lockfile"; $fp = fopen($lockFile, "w+"); if ($fp === false) { return false; } $res = true; if (flock($fp, LOCK_EX)) { $newFile = FALSE; if (!file_exists($this->statsFilePath)) { $res = $this->_generateXml(); } if ($res) { $dom = new DomDocument("1.0","UTF-8"); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $res = $dom->load($this->statsFilePath); if (!$newFile) { // add missing tasks if needed $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs); $newTask = FALSE; foreach ($allTasks as $task) { $items = $dom->getElementsByTagName($task); if ($items->length == 0) { //add missing task $element = $dom->createElement("$task"); $dom->documentElement->appendChild($element); $newTask = TRUE; } } if ($newTask) { $dom->save($this->statsFilePath); } } if ($res) { $func_res = call_user_func($callback,$dom, $options); } } } else $res = false; fclose($fp); if ($res) return $func_res; return false; } private function _generateXml() { $dom = new DomDocument("1.0","UTF-8"); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $rootElement = $dom->createElement('stats'); $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs); foreach ($allTasks as $task) { $element = $dom->createElement("$task"); $rootElement->appendChild($element); } $dom->appendChild($rootElement); return $dom->save($this->statsFilePath); } /* * Merge individual User Stats.xml into one generique Stats.xml */ private function _mergeXml($dom, $options) { // long procedure ini_set('max_execution_time', 600); $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs); $userDoc = new DomDocument("1.0"); if ($options['year'] == null) $options['year'] = date("Y"); $users=glob(USERPATH."*"); foreach ($users as $user) { $userXmlPath = $user."/Stats".$options['year'].".xml"; if (!file_exists($userXmlPath)) continue; $userDoc->load($userXmlPath); foreach ($allTasks as $task) { $globalTaskItems = $dom->getElementsByTagName($task); if ($globalTaskItems->length == 0) continue; $globalTaskItem = $globalTaskItems->item(0); $userTaskItems = $userDoc->getElementsByTagName($task); if ($userTaskItems->length == 0) continue; $userTaskItem = $userTaskItems->item(0); $userItems = $userTaskItem->getElementsByTagName("item"); if ($userItems->length > 0) { foreach ($userItems as $userItem) { $globalItem = $dom->importNode($userItem, true); $globalTaskItem->appendChild($globalItem); } } } } // write task statistics as json $this->_getModulesStat($dom, array('start' => null, 'stop' => null, 'update' => TRUE)); // write data statistics as json $this->_getDataStat($dom, array('index' => 0, 'start', null, 'stop' => null, 'update' => true)); return $dom->save($this->statsFilePath); } private function _addTask($dom, $options) { if ($options['task'] == 'killplot') return FALSE; if ($options['vars']) $realTask = $this->task[$options['task']]; else $realTask = $options['task']; if (!in_array($options['user'], $this->usersToExclude)) { $taskElementNode = $dom->getElementsByTagName("$realTask"); if ($taskElementNode->length < 1) return; $taskElement = $taskElementNode->item(0); if (is_object($taskElement)) { $newTask = $dom->createElement('item'); $newTask->setAttribute('date', date('Y-m-d')); $newTask->setAttribute('user', $options['user']); if ($options['vars']) { $ID = array(); foreach ($options['vars'] as $var) { $ID[] = $var; } $ID = array_unique($ID); foreach ($ID as $id) { $datasetElement = $dom->createElement('dataset', $id); $newTask->appendChild($datasetElement); } } $taskElement->appendChild($newTask); return $dom->save($this->statsFilePath); } else error_log('Check Stats.xml - no task element '.$options['task'], 1, email); } return FALSE; } /* * Show Statistics */ private function _getModulesStat($dom, $options){ if (!$options['update'] && file_exists(DATAPATH.'Statistics/tasks.json')) { return file_get_contents(DATAPATH.'Statistics/tasks.json'); } $taskArray = array(); foreach (array_merge($this->tasks,$this->tasksAdd, $this->tasksWs) as $task) { $taskItems = $dom->getElementsByTagName($task); if ($taskItems->length < 1) return; $theTask = $taskItems->item(0); $items = $theTask->getElementsByTagName('item'); $hints = $items->length; $startStop = $this->getStartStop($items, $options['start'], $options['stop']); $taskArray[] = array('task' => $task, 'number' => $hints, 'start' => $startStop[0], 'stop' => $startStop[1]); } $objToReturn = json_encode(array('stats' => $taskArray)); file_put_contents(DATAPATH.'Statistics/tasks.json', $objToReturn); return $objToReturn; } /* * Show Statistics */ private function _getDataStat($dom, $options){ if (!$options['update'] && file_exists(DATAPATH.'Statistics/data.json')) { $GENERALarray = json_decode(file_get_contents(DATAPATH.'Statistics/data.json')); } else { $VIarray = array(); $TOTALarray = array(); $STARTarray = array(); $STOParray = array(); $usersArray = array(); $dataTasks = array_merge($this->tasks, $this->tasksWs); foreach ($dataTasks as $task) { $taskItems = $dom->getElementsByTagName($task); if ($taskItems->length < 1) continue; $theTask = $taskItems->item(0); $items = $theTask->getElementsByTagName('item'); $TASKarray = array(); foreach ($items as $item){ $VIs = $item->getElementsByTagName('dataset'); $time = strtotime($item->getAttribute('date')); $user = $item->getAttribute('user'); foreach ($VIs as $VI) { $id = $VI->nodeValue; if ($id) { if (!in_array($id, $usersArray)) { $usersArray[$id] = array(); } if (!in_array($user, $usersArray[$id])) { $usersArray[$id][$user] = 0; } $usersArray[$id][$user]++; if (array_key_exists($id, $TASKarray)) { $TASKarray[$id]++; $TOTALarray[$id]++; if ($STARTarray[$id] > $time) $STARTarray[$id] = $time; if ($STOParray[$id] < $time) $STOParray[$id] = $time; } else { if (!array_key_exists($id,$TOTALarray)) { $STARTarray[$id] = $time; $STOParray[$id] = $time; $TOTALarray[$id] = 1; } else { if ($STARTarray[$id] > $time) $STARTarray[$id] = $time; if ($STOParray[$id] < $time) $STOParray[$id] = $time; $TOTALarray[$id]++; } $TASKarray[$id] = 1; } } } } $VIarray[$task] = $TASKarray; } $GENERALarray = array(); arsort($TOTALarray); $Ntotal = 0; foreach ($TOTALarray as $key => $value) { $viStart = $STARTarray[$key]; $viStop = $STOParray[$key]; $plot = (empty($VIarray['plot']) || empty($VIarray['plot'][$key])) ? 0 : $VIarray['plot'][$key]; $mining = (empty($VIarray['mining']) || empty($VIarray['mining'][$key])) ? 0 : $VIarray['mining'][$key]; $print = (empty($VIarray['print']) || empty($VIarray['print'][$key])) ? 0 : $VIarray['print'][$key]; $stat = (empty($VIarray['statistics']) || empty($VIarray['statistics'][$key])) ? 0 : $VIarray['statistics'][$key]; $ws_print = (empty($VIarray['ws_print']) || empty($VIarray['ws_print'][$key])) ? 0 : $VIarray['ws_print'][$key]; $ws_plot = (empty($VIarray['ws_plot']) || empty($VIarray['ws_plot'][$key])) ? 0 : $VIarray['ws_plot'][$key]; $uniqueUsers = count($usersArray[$key]); if ($key != 'undefined') { $GENERALarray[] = array('id' => $key, 'number' => $value, 'percent' => $value, 'plot' => $plot, 'mining' => $mining, 'print' => $print,'statistics' => $stat, 'ws_print' => $ws_print, 'ws_plot' => $ws_plot, 'start' => $viStart, 'stop' => $viStop, 'unique' => $uniqueUsers); $Ntotal += $value; } } $Ntotal /= 100; foreach ($GENERALarray as &$elem) { $elem['percent'] = round($elem['percent'] / $Ntotal, 2); } } $Nmax = count($GENERALarray); $length = $options['index'] + 20 > $Nmax ? $Nmax - $options['index'] + 1 : 20; $objToReturn = array('stats' => array_reverse(array_slice($GENERALarray, $options['index'], $length))); file_put_contents(DATAPATH.'Statistics/data.json',json_encode($GENERALarray)); // $objToReturn = array('stats' => $GENERALarray); return $objToReturn; } public function getStartStop($items, $start, $stop) { if (!$start) $start = 0; if (!$stop) $stop = 100000000000; $date = array(); if ($items->length < 1) { return array(0, 0); } else { foreach ($items as $item) { $newDate = strtotime($item->getAttribute('date')); if (($newDate > $start) && ($newDate < $stop)) $date[] = $newDate; } } return array(min($date), max($date)); } private function _mergeStats($dom, $options) { if (!file_exists($options['inXml'])) return 0; $tags = array_merge($this->tasks,$this->tasksAdd, $this->tasksWs); $doc2 = new DomDocument("1.0"); if (!$doc2->load($options['inXml'])) return 0; foreach ($tags as $tag){ $tag1 = $dom->getElementsByTagName($tag)->item(0); $tag2 = $doc2->getElementsByTagName($tag)->item(0); $items2 = $tag2->getElementsByTagName("item"); if ($items2->length > 0) { foreach ($items2 as $item2) { $item1 = $dom->importNode($item2, true); $tag1->appendChild($item1); } } } return $dom->save($this->statsFilePath); } } ?>