1<?php
2
3require dirname(__FILE__) . '/pchart/pData.php';
4require dirname(__FILE__) . '/pchart/pChart.php';
5require dirname(__FILE__) . '/pchart/GDCanvas.php';
6require dirname(__FILE__) . '/pchart/PieChart.php';
7
8class 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