1 <?php
2 
3 require dirname(__FILE__) . '/pchart/pData.php';
4 require dirname(__FILE__) . '/pchart/pChart.php';
5 require dirname(__FILE__) . '/pchart/GDCanvas.php';
6 require dirname(__FILE__) . '/pchart/PieChart.php';
7 
8 class StatisticsGraph {
9     private $hlp;
10     private $tlimit;
11     private $start;
12     private $from;
13     private $to;
14 
15     public function __construct(helper_plugin_statistics $hlp) {
16         $this->hlp = $hlp;
17     }
18 
19     public function render($call, $from, $to, $start) {
20         $from = preg_replace('/[^\d\-]+/', '', $from);
21         $to   = preg_replace('/[^\d\-]+/', '', $to);
22         if(!$from) $from = date('Y-m-d');
23         if(!$to) $to = date('Y-m-d');
24         $this->tlimit = "A.dt >= '$from 00:00:00' AND A.dt <= '$to 23:59:59'";
25         $this->start  = (int) $start;
26         $this->from   = $from;
27         $this->to     = $to;
28 
29         if(method_exists($this, $call)) {
30             $this->$call();
31         } else {
32             $this->hlp->sendGIF();
33         }
34     }
35 
36     /**
37      * Create a PieChart
38      *
39      * @param array $data associative array contianing label and values
40      */
41     protected function PieChart($data) {
42         $DataSet = new pData;
43         $Canvas  = new GDCanvas(400, 200, false);
44         $Chart   = new PieChart(400, 200, $Canvas);
45         $Chart->setFontProperties(dirname(__FILE__) . '/pchart/Fonts/DroidSans.ttf', 8);
46 
47         $DataSet->AddPoints(array_values($data), 'Serie1');
48         $DataSet->AddPoints(array_keys($data), 'Serie2');
49         $DataSet->AddAllSeries();
50         $DataSet->SetAbscissaLabelSeries("Serie2");
51 
52         $Chart->drawBasicPieGraph(
53             $DataSet->getData(),
54             $DataSet->GetDataDescription(),
55             120, 100, 60, PIE_PERCENTAGE
56         );
57         $Chart->drawPieLegend(
58             230, 15,
59             $DataSet->GetData(),
60             $DataSet->GetDataDescription(),
61             new Color(250)
62         );
63 
64         header('Content-Type: image/png');
65         $Chart->Render('');
66     }
67 
68     /**
69      * Build a PieChart with only the top data shown and all other summarized
70      *
71      * @param string $query The function to call on the Query object to get the data
72      * @param string $key The key containing the label
73      * @param int $max How many discrete values to show before summarizing under "other"
74      */
75     protected function sumUpPieChart($query, $key, $max=4){
76         $result = $this->hlp->Query()->$query($this->tlimit, $this->start, 0, false);
77         $data   = array();
78         $top    = 0;
79         foreach($result as $row) {
80             if($top < $max) {
81                 $data[$row[$key]] = $row['cnt'];
82             } else {
83                 $data['other'] += $row['cnt'];
84             }
85             $top++;
86         }
87         $this->PieChart($data);
88     }
89 
90     /**
91      * Create a history graph for the given info type
92      *
93      * @param $info
94      */
95     protected function history($info) {
96         $diff = abs(strtotime($this->from) - strtotime($this->to));
97         $days = floor($diff / (60*60*24));
98         if ($days > 365) {
99             $interval= 'months';
100         } elseif ($days > 56) {
101             $interval = 'weeks';
102         } else {
103             $interval = 'days';
104         }
105 
106         $result = $this->hlp->Query()->history($this->tlimit, $info, $interval);
107 
108         $data = array();
109         $times = array();
110         foreach($result as $row) {
111             $data[] = $row['cnt'];
112             if($interval == 'months') {
113                 $times[] = substr($row['time'], 0, 4) . '-' . substr($row['time'], 4, 2);
114             } elseif ($interval == 'weeks') {
115                 $times[] = $row['EXTRACT(YEAR FROM dt)'] . '-' . $row['time'];
116             }else {
117                 $times[] = substr($row['time'], -5);
118             }
119         }
120 
121         $DataSet = new pData();
122         $DataSet->AddPoints($data, 'Serie1');
123         $DataSet->AddPoints($times, 'Times');
124         $DataSet->AddAllSeries();
125         $DataSet->SetAbscissaLabelSeries('Times');
126 
127         $DataSet->setXAxisName($this->hlp->getLang($interval));
128         $DataSet->setYAxisName($this->hlp->getLang('graph_'.$info));
129 
130         $Canvas = new GDCanvas(600, 200, false);
131         $Chart  = new pChart(600, 200, $Canvas);
132 
133         $Chart->setFontProperties(dirname(__FILE__) . '/pchart/Fonts/DroidSans.ttf', 8);
134         $Chart->setGraphArea(70, 15, 580, 140);
135         $Chart->drawScale(
136             $DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
137             45, 1, false, ceil(count($times) / 12)
138         );
139         $Chart->drawLineGraph($DataSet->GetData(), $DataSet->GetDataDescription());
140 
141         $DataSet->removeSeries('Times');
142         $DataSet->removeSeriesName('Times');
143 
144 
145         header('Content-Type: image/png');
146         $Chart->Render('');
147     }
148 
149     #region Graphbuilding functions
150 
151     public function countries() {
152         $this->sumUpPieChart('countries', 'country');
153     }
154 
155     public function searchengines() {
156         $this->sumUpPieChart('searchengines', 'engine', 3);
157     }
158 
159     public function browsers() {
160         $this->sumUpPieChart('browsers', 'ua_info');
161     }
162 
163     public function os() {
164         $this->sumUpPieChart('os', 'os');
165     }
166 
167     public function topuser() {
168         $this->sumUpPieChart('topuser', 'user');
169     }
170 
171     public function topeditor() {
172         $this->sumUpPieChart('topeditor', 'user');
173     }
174 
175     public function topgroup() {
176         $this->sumUpPieChart('topgroup', 'group');
177     }
178 
179     public function topgroupedit() {
180         $this->sumUpPieChart('topgroupedit', 'group');
181     }
182 
183     public function viewport() {
184         $result = $this->hlp->Query()->viewport($this->tlimit, 0, 100);
185         $data1  = array();
186         $data2  = array();
187         $data3  = array();
188 
189         foreach($result as $row) {
190             $data1[] = $row['res_x'];
191             $data2[] = $row['res_y'];
192             $data3[] = $row['cnt'];
193         }
194 
195         $DataSet = new pData;
196         $DataSet->AddPoints($data1, 'Serie1');
197         $DataSet->AddPoints($data2, 'Serie2');
198         $DataSet->AddPoints($data3, 'Serie3');
199         $DataSet->AddAllSeries();
200 
201         $Canvas = new GDCanvas(650, 490, false);
202         $Chart  = new pChart(650, 490, $Canvas);
203 
204         $Chart->setFontProperties(dirname(__FILE__) . '/pchart/Fonts/DroidSans.ttf', 8);
205         $Chart->setGraphArea(50, 30, 630, 470);
206         $Chart->drawXYScale(
207             $DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
208             'Serie2', 'Serie1'
209         );
210 
211         $Chart->drawXYPlotGraph($DataSet, 'Serie2', 'Serie1', 0, 20, 2, null, false, 'Serie3');
212         header('Content-Type: image/png');
213         $Chart->Render('');
214     }
215 
216     public function resolution() {
217         $result = $this->hlp->Query()->resolution($this->tlimit, 0, 100);
218         $data1  = array();
219         $data2  = array();
220         $data3  = array();
221 
222         foreach($result as $row) {
223             $data1[] = $row['res_x'];
224             $data2[] = $row['res_y'];
225             $data3[] = $row['cnt'];
226         }
227 
228         $DataSet = new pData;
229         $DataSet->AddPoints($data1, 'Serie1');
230         $DataSet->AddPoints($data2, 'Serie2');
231         $DataSet->AddPoints($data3, 'Serie3');
232         $DataSet->AddAllSeries();
233 
234         $Canvas = new GDCanvas(650, 490, false);
235         $Chart  = new pChart(650, 490, $Canvas);
236 
237         $Chart->setFontProperties(dirname(__FILE__) . '/pchart/Fonts/DroidSans.ttf', 8);
238         $Chart->setGraphArea(50, 30, 630, 470);
239         $Chart->drawXYScale(
240             $DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
241             'Serie2', 'Serie1'
242         );
243 
244         $Chart->drawXYPlotGraph($DataSet, 'Serie2', 'Serie1', 0, 20, 2, null, false, 'Serie3');
245         header('Content-Type: image/png');
246         $Chart->Render('');
247     }
248 
249 
250     public function history_page_count() {
251         $this->history('page_count');
252     }
253 
254     public function history_page_size() {
255         $this->history('page_size');
256     }
257 
258     public function history_media_count() {
259         $this->history('media_count');
260     }
261 
262     public function history_media_size() {
263         $this->history('media_size');
264     }
265 
266 
267     public function dashboardviews() {
268         $hours  = ($this->from == $this->to);
269         $result = $this->hlp->Query()->dashboardviews($this->tlimit, $hours);
270         $data1  = array();
271         $data2  = array();
272         $data3  = array();
273         $times  = array();
274 
275         foreach($result as $time => $row) {
276             $data1[] = (int) $row['pageviews'];
277             $data2[] = (int) $row['sessions'];
278             $data3[] = (int) $row['visitors'];
279             $times[] = $time . ($hours ? 'h' : '');
280         }
281 
282         $DataSet = new pData();
283         $DataSet->AddPoints($data1, 'Serie1');
284         $DataSet->AddPoints($data2, 'Serie2');
285         $DataSet->AddPoints($data3, 'Serie3');
286         $DataSet->AddPoints($times, 'Times');
287         $DataSet->AddAllSeries();
288         $DataSet->SetAbscissaLabelSeries('Times');
289 
290         $DataSet->SetSeriesName($this->hlp->getLang('graph_views'), 'Serie1');
291         $DataSet->SetSeriesName($this->hlp->getLang('graph_sessions'), 'Serie2');
292         $DataSet->SetSeriesName($this->hlp->getLang('graph_visitors'), 'Serie3');
293 
294         $Canvas = new GDCanvas(700, 280, false);
295         $Chart  = new pChart(700, 280, $Canvas);
296 
297         $Chart->setFontProperties(dirname(__FILE__) . '/pchart/Fonts/DroidSans.ttf', 8);
298         $Chart->setGraphArea(50, 10, 680, 200);
299         $Chart->drawScale(
300             $DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
301             ($hours ? 0 : 45), 1, false, ceil(count($times) / 12)
302         );
303         $Chart->drawLineGraph($DataSet->GetData(), $DataSet->GetDataDescription());
304 
305         $DataSet->removeSeries('Times');
306         $DataSet->removeSeriesName('Times');
307         $Chart->drawLegend(
308             550, 15,
309             $DataSet->GetDataDescription(),
310             new Color(250)
311         );
312 
313         header('Content-Type: image/png');
314         $Chart->Render('');
315     }
316 
317     public function dashboardwiki() {
318         $hours  = ($this->from == $this->to);
319         $result = $this->hlp->Query()->dashboardwiki($this->tlimit, $hours);
320         $data1  = array();
321         $data2  = array();
322         $data3  = array();
323         $times  = array();
324 
325         foreach($result as $time => $row) {
326             $data1[] = (int) $row['E'];
327             $data2[] = (int) $row['C'];
328             $data3[] = (int) $row['D'];
329             $times[] = $time . ($hours ? 'h' : '');
330         }
331 
332         $DataSet = new pData();
333         $DataSet->AddPoints($data1, 'Serie1');
334         $DataSet->AddPoints($data2, 'Serie2');
335         $DataSet->AddPoints($data3, 'Serie3');
336         $DataSet->AddPoints($times, 'Times');
337         $DataSet->AddAllSeries();
338         $DataSet->SetAbscissaLabelSeries('Times');
339 
340         $DataSet->SetSeriesName($this->hlp->getLang('graph_edits'), 'Serie1');
341         $DataSet->SetSeriesName($this->hlp->getLang('graph_creates'), 'Serie2');
342         $DataSet->SetSeriesName($this->hlp->getLang('graph_deletions'), 'Serie3');
343 
344         $Canvas = new GDCanvas(700, 280, false);
345         $Chart  = new pChart(700, 280, $Canvas);
346 
347         $Chart->setFontProperties(dirname(__FILE__) . '/pchart/Fonts/DroidSans.ttf', 8);
348         $Chart->setGraphArea(50, 10, 680, 200);
349         $Chart->drawScale(
350             $DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
351             ($hours ? 0 : 45), 1, false, ceil(count($times) / 12)
352         );
353         $Chart->drawLineGraph($DataSet->GetData(), $DataSet->GetDataDescription());
354 
355         $DataSet->removeSeries('Times');
356         $DataSet->removeSeriesName('Times');
357         $Chart->drawLegend(
358             550, 15,
359             $DataSet->GetDataDescription(),
360             new Color(250)
361         );
362 
363         header('Content-Type: image/png');
364         $Chart->Render('');
365     }
366 
367     #endregion Graphbuilding functions
368 }
369