1<?php
2
3if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) .'/../../../../') . '/');
4
5require_once DOKU_INC . 'inc/init.php';
6require_once DOKU_INC . 'inc/io.php';
7
8require DOKU_INC . 'lib/plugins/quickstats/GEOIP/cc_arrays_dat.php';
9//display_post_data();
10global $UserAgentArray, $INPUT;
11global $PAGE_USERS_ARRAY;
12$UserAgentArray = false;
13$PAGE_USERS_ARRAY = false;
14if(isset($_REQUEST['qs_script_max_time'])) {
15    $script_max_time = $INPUT->int('qs_script_max_time');
16}
17else {
18   $script_max_time = 60;
19}
20
21 if( !ini_get('safe_mode') ){
22          set_time_limit($script_max_time);
23 }
24
25$qs_start_time=time();
26
27$priority = "";
28qs_formatQuery() ;
29echo "<div id='quickstats_admin_disp'>";
30if(isset($_POST['priority']) && $_POST['priority']) {
31    $priority = $INPUT->str('priority');
32    if($priority == 'country' && isset($_POST['user_agent'])) {
33        $priority = 'agent';
34    }
35}
36
37switch ($priority) {
38case 'page':
39    $page = rawurldecode($INPUT->str('page'));
40    $keys =array_keys($_POST);
41    foreach($keys as $key) {
42         if(strpos($key,'date') !== false) {
43          $temp = array();
44          $month = rawurldecode($INPUT->str($key));
45          $temp =  qs_process_pages ($page,$month);
46          qs_format_pages($temp, $month);
47         }
48    }
49    break;
50case 'ip':
51   if(isset($_POST['ip']) && $_POST['ip']) {
52      echo rawurlencode(ip_data()) . "\n";
53   }
54    break;
55case 'country':
56   if(isset($_POST['country_code']) && $_POST['country_code']) {
57      qs_process_country($_POST['country_code'],$_POST['country_name']) . "\n";
58   }
59    break;
60case 'agent':
61   if(isset($_POST['user_agent'])) {
62      qs_process_agents($_POST['user_agent']);
63   }
64    break;
65default:
66  echo "Please check your query.  It cannot be completed in its present form.  You do not seem to have chosen a priority.<br />";
67  echo "If this persists, please post an error report either to  the quickstats site at https://github.com/turnermm/quickstats<br />or to the quickstats page at http://www.dokuwiki.org/plugin:quickstats.";
68
69
70}
71echo "<b>Total Accesses: " . qs_total_accesses(0) . '</b>';
72$extime = time() - $qs_start_time;
73if($extime) {
74    echo "<br /><b>Execution Time: " . $extime . ' seconds</b>';
75}
76echo '</div>';
77exit;
78
79function qs_total_accesses($n) {
80static $total=0;
81    if(is_numeric($n)) {
82        $total += $n;
83   }
84   return $total;
85}
86function ip_data($ip=false,$p_brief=false) {
87   $row = "";
88   $table = '<table border=1 cellspacing="0">';
89   $date = rawurldecode($_POST['date']);
90   if($ip === false)  $ip =rawurldecode($_POST['ip']);
91
92
93  if($p_brief) {
94    $result = ip_row(array('ip','ua'), $ip,$date);
95    if($result) {
96        $table .= '<tr>' . cell("$ip ",'caption',false,$p_brief) . '</tr>';
97        $table .= qs_header(array('month','access','country','agent'));
98        $table .= $result;
99    }
100  }
101  else  {
102      $result = ip_row(array('ip','page_users','ua', 'qs_data'), $ip,$date);
103      if($result) {
104          $table .= '<tr>' . cell("Data for IP address:  $ip ",'caption',false,$p_brief) . '</tr>';
105          $table .= qs_header(array('month','access','page','country','agent','search','ns','name','val'));
106          $table .= $result;
107      }
108  }
109
110  $keys = $keys =array_keys($_POST);
111  foreach($keys as $key) {
112     if(strpos($key,'date_') !== false) {
113         $date = rawurldecode($_POST[$key]);
114         $table .= '<tr>' . cell('&nbsp;', $type='td', $colspan='9') . '</tr>';
115
116         if($p_brief) {
117            $table .= ip_row(array('ip','ua'), $ip,$date);
118          }
119            else  {
120             $table .= ip_row(array('ip','page_users','ua', 'qs_data'), $ip,$date);
121            }
122
123     }
124  }
125  return $table . '</table>';
126}
127
128function qs_data(&$ar,$ip) {
129           $search_terms = "";
130           if(!is_array($ar)) return cell('&nbsp;&nbsp;&nbsp;');
131           foreach($ar as $word =>$data) {
132               $word = htmlentities($word);
133               $word = str_replace('%','&#37;',$word);
134                if(isset($data[$ip])) {
135                   $search_terms .= "&nbsp;&nbsp;&nbsp;$word (" .  $data[$ip] . ')<br />';
136                }
137            }
138            if($search_terms) {
139                return cell($search_terms);
140             }
141             else  return cell('&nbsp;&nbsp;&nbsp;');
142
143
144}
145
146function qs_check_time() {
147   global $qs_start_time, $script_max_time;
148   $tm=time();
149   if($tm-$qs_start_time > $script_max_time-1) {
150      echo "<b>Timed out after $script_max_time seconds.  See the Query How-To </b><br /><br />";
151	  exit;
152   }
153}
154
155function ip_row($which,$index,$date,$show_country=true, $show_ip=false,$check_agent=false) {
156   global $UserAgentArray;
157   global $PAGE_USERS_ARRAY;
158   $accesses = 0;
159   if(isset($_POST['country_code'])) {
160     $country_code = rawurldecode($_POST['country_code']);
161   }
162   else $country_code = false;
163qs_check_time();
164   $row = '<tr>';
165   if($show_ip) {
166      $row .= cell($index,'th');
167   }
168   $row .= cell(str_replace('_','/',$date). '&nbsp;&nbsp;&nbsp;');
169
170   foreach($which as $type) {
171     if($type == 'ua' && $UserAgentArray !== false) {
172         $temp = $UserAgentArray;
173     }
174     else if ($type == 'page_users' && $PAGE_USERS_ARRAY !== false) {
175         $temp = $PAGE_USERS_ARRAY;
176     }
177     else $temp = load_data($type,$date);
178
179        if($type == 'qs_data' ) {
180             if(!empty($temp)) {
181                $row .= qs_data($temp['words'] ,$index);
182                $row .= qs_data($temp['ns'] ,$index);
183                $row .= qs_data($temp['extern']['name'] ,$index);
184                $row .= qs_data($temp['extern']['val'] ,$index);
185             }
186             else $row .= cell('&nbsp;') . cell('&nbsp;') . cell('&nbsp;') . cell('&nbsp;');
187      }
188
189      else if(!empty($temp) && isset($temp[$index])) {
190              if($type == 'page_users') {
191                  sort($temp[$index]);
192                  $row .= cell(implode('<br />',$temp[$index]));
193              }
194              else if($type == 'ua') {
195                   $data = $temp[$index];
196                    $cc = array_shift($data);
197                    $country=qs_get_country_name($cc) ;
198                    if($country_code && $cc != $country_code) {
199                        //return cell("Country of IP ($country) does not match: " . qs_get_country_name($country_code),'td',9 );
200                        return null;
201                    }
202                    $uas = '&nbsp;&nbsp;' . implode('<br />&nbsp;&nbsp;',$data);
203                    if($check_agent && strpos($uas,  $check_agent) === false) return null;
204                    if($show_country) $row .= cell('&nbsp;&nbsp;&nbsp;' ." $country");
205                    $row .= cell($uas);
206              }
207              else {
208                  $row .= cell($temp[$index]);
209                  $accesses += $temp[$index];
210              }
211     }
212     else {
213         $row .= cell('&nbsp;');
214    }
215  }
216  if($row) {
217     qs_total_accesses($accesses);
218  }
219  return $row . '</tr>';
220}
221
222function qs_header($which) {
223    $thds = array('ip'=>'IP', 'month'=>'Month',  'access'=>'Accesses', 'page'=>'Pages','country'=>'Country', 'agent'=>'UserAgent', 'search'=>'Search Terms',
224                      'ns'=>'Namespaces', 'name'=>'Query String<br />Names', 'val'=>'Query String<br />Values');
225    $header ='<tr>';
226    foreach($which as $th) {
227       $header .= cell($thds[$th],'th');
228    }
229    return $header . '</tr>';
230}
231
232function cell($data, $type='td', $colspan="",$p_brief=false) {
233  $class = "padded";
234  if($colspan) $colspan = "colspan='$colspan'";
235  if($type == 'caption' && !$p_brief) {
236     $class .= ' qs_cap';
237   }
238   else if($type == 'caption' ) {
239       $class .= ' qs_bold_left';
240  }
241
242
243   return "<$type class='$class' $colspan nowrap valign='top'>$data</$type>";
244}
245
246function load_data($which,$date) {
247
248    $meta_path = rawurldecode($_POST['meta_path']);
249    $file['ip'] =  $meta_path . $date .'/ip.ser';
250    $file['misc_data'] = $meta_path . $date .'/misc_data.ser';
251    $file['pages'] =$meta_path . $date .'/pages.ser';
252    $file['ua'] =$meta_path . $date .'/ua.ser';
253    $file['qs_data'] =$meta_path . $date .'/qs_data.ser';
254    $file['page_users'] =$meta_path . $date .'/page_users.ser';
255    $file['page_totals'] = $meta_path .'page_totals.ser';
256    $temp= unserialize(io_readFile($file[$which],false));
257    if(!$temp) $temp = array();
258    return $temp;
259
260}
261
262function get_page_row($ip, $date, $p_brief=false,$agent=false) {
263  $table = "";
264  if($p_brief) {
265    $result = ip_row(array('ip','ua'), $ip,$date,true,true,$agent);
266    if($result) {
267        $table .= $result;
268    }
269  }
270  else  {
271      $result = ip_row(array('ip','page_users','ua', 'qs_data'), $ip,$date,true,false,$agent);
272      if($result) {
273          $table .= '<tr>' . cell("Data for IP address:  $ip ",'caption',false,$p_brief) . '</tr>';
274          $table .= qs_header(array('month','access','page','country','agent','search','ns','name','val'));
275          $table .= $result;
276      }
277  }
278  return $table;
279 }
280
281/**
282 *  @param $pages: array returned from qs_process_pages()
283 *  outputs header of page name and page access, then ip data for the ip using ip_row
284 */
285function qs_format_pages($pages,$month) {
286   global $PAGE_USERS_ARRAY;
287   $PAGE_USERS_ARRAY = load_data('page_users',$month);
288   if(isset($_POST['user_agent'])) {
289       $agent = $_POST['user_agent'];
290   }
291    else $agent = false;
292
293    if(isset($_POST['p_brief'])) {
294        foreach($pages as $page=>$ar) {
295            $page = rawurlencode($page);
296            $header = "<h1>$page</h1>\n";
297            $header .=  '<div class="level2 qs_brief"><h3>Total accesses for  ' . $page . ': '  . $ar['accesses'] . '</h3>' . "\n";
298            $header .=  "<table cellspacing='0' class='qs_brief_table'>\n";
299
300            $header_displayed = false;
301            $close_div = false;
302            foreach($ar['ips'] as $ip) {
303                $ipdata = get_page_row($ip, $month, isset($_POST['p_brief']),$agent) ;
304                if($ipdata) {
305                    if(!$header_displayed) {
306                        echo $header;
307                        echo qs_header(array('ip','month','access','country','agent'));
308                        $header_displayed = true;
309                        $close_div = true;
310                    }
311                    echo rawurlencode($ipdata);
312                }
313            }
314            if($close_div) echo "</table></div>\n";
315        }
316    }
317    else {
318        foreach($pages as $page=>$ar) {
319            $page = rawurlencode($page);
320            foreach($ar['ips'] as $ip) {
321                $ipdata = get_page_row($ip, $month, isset($_POST['p_brief']),$agent) ;
322                if($ipdata) {
323                    echo "<h1>$page</h1>\n";
324                    echo '<div class="level2"><h3>Total accesses for  ' . $page . ': '  . $ar['accesses'] . '</h3>' . "\n<table>\n";
325                    echo rawurlencode($ipdata);
326                    echo "</table></div>\n";
327                }
328            }
329        }
330    }
331}
332
333  /**
334  *  @param $needle: page name or partial name from $_POST
335  *  @param $month: formatted for path name: month_year
336  *  @return:  array of page_names=>accesses for qs_format_pages()
337  */
338 function qs_pages_search_i ($needle = null,$month)
339 {
340
341    $pages = load_data('pages',$month);
342    if(!isset($pages['page'])) {
343       return array();
344    }
345    if(isset($pages['page'][$needle]))return array($needle=>$pages['page'][$needle]);
346    $ret_ar = array();
347    foreach($pages['page'] as $key => $val)
348    {
349
350        if(stristr($key, $needle) !== false) {
351             $ret_ar[$key] = $val;
352         }
353
354    }
355
356    return $ret_ar;
357
358 }
359
360  /**
361  *  @param $page: page name or partial name from $_POST
362  *  @return array of [page_names] = array(accesses=>integer, ips=>array(ip_addresses))
363  */
364 function qs_process_pages ($page, $month) {
365   $temp = array();
366   $page_users = load_data('page_users',$month);
367   $found = qs_pages_search_i($page,$month);
368   if(!$found) {
369       return $temp;
370    }
371
372   foreach($found as $page=>$accesses) {
373       if(isset($page_users[md5($page)])) {
374           $temp[$page] = array('accesses'=>$accesses, 'ips'=>$page_users[md5($page)]);
375       }
376   }
377
378   return $temp;
379 }
380
381 function qs_output_countries($date,$cc,$country) {
382   global $UserAgentArray;
383    $ua_data = load_data('ua',$date);
384    $UserAgentArray = $ua_data;
385    if(!empty($ua_data)) {
386        foreach($ua_data as $ip=>$ar) {
387           if(isset($ar[0]) && $ar[0] == $cc) {
388               echo rawurlencode(ip_row(array('ip','page_users','ua', 'qs_data'), $ip,$date,false,true));
389               echo "\n";
390           }
391        }
392   }
393 $UserAgentArray = false;
394 }
395
396 function qs_process_country($cc,$country_name) {
397    $p_brief = false;
398    echo '<table border cellspacing="0">';
399    echo rawurlencode(cell($country_name,'caption') ."\n");
400    echo qs_header(array('ip','month','access','page','agent','search','ns','name','val'));
401    $date = rawurldecode($_POST['date']);
402    qs_output_countries($date,$cc,$country_name) ;
403
404    $keys =array_keys($_POST);
405    foreach($keys as $key) {
406         if(strpos($key,'date_') !== false) {
407           $date = rawurldecode($_POST[$key]);
408            qs_output_countries($date,$cc,$country_name) ;
409         }
410       }
411       echo '</table>';
412 }
413
414 function qs_output_agents($agents,$date)  {
415          foreach($agents as $ip) {
416              echo rawurlencode(ip_row(array('ip','page_users','ua', 'qs_data'), $ip,$date,true,true));
417          }
418
419 }
420
421 function qs_process_agents($agent=null) {
422   if(!$agent) return;
423    echo '<table border cellspacing="0">';
424    echo rawurlencode(cell($agent,'caption') ."\n");
425
426    echo qs_header(array('ip','month','access','page','country','agent','search','ns','name','val'));
427    $date = rawurldecode($_POST['date']);
428    $agents = qs_agent_search_i ($agent,$date);
429    qs_output_agents($agents,$date) ;
430
431   $keys =array_keys($_POST);
432    foreach($keys as $key) {
433         if(strpos($key,'date_') !== false) {
434           $date = rawurldecode($_POST[$key]);
435          $agents = qs_agent_search_i ($agent,$date) ;
436           qs_output_agents($agents,$date) ;
437         }
438       }
439       echo '</table>';
440 }
441
442 function qs_agent_search_i ($needle = null,$month)
443 {
444  global $agents;
445   $agents = load_data('ua',$month);
446   $ret_ar = array();
447
448    foreach($agents as $ip => $val)
449    {
450        if(isset($val[1]) && stristr($val[1], $needle) !== false) {
451             //$ret_ar[$key] = $val;
452             $ret_ar[] = $ip;
453         }
454    }
455    return $ret_ar;
456
457 }
458
459function qs_formatQuery() {
460    global $INPUT;
461    $months = array("",'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
462    $fields = array('country_name'=>'Country',  'user_agent'=>'User Agent',  'priority'=>'Priority',  'ip'=>'IP Address',
463                           'page'=>'&lt;Namespace:&gt;Page',  'date'=>'Month/Year' );
464
465    $ip_set = false;
466    $priority = false;
467
468    echo "\n" . '<table><tr><th class="thead">Query</th><tr>' . "\n";
469    $str = "";
470    foreach($fields as $field=>$label) {
471        if(!isset($_POST[$field])) continue;
472        $value = rawurldecode($INPUT->str($field));
473        switch($field) {
474            case 'date':
475                $str .= "<th align='right'>$label:&nbsp;</th><td>";
476                $keys=array_keys($_POST);
477                foreach($keys as $key) {
478                    if(strpos($key,'date') !== false) {
479                       list($mon,$year) =   explode('_',$_POST[$key]);
480                       $str .=  $months[$mon] . ' ' . $year .' &nbsp;';
481                    }
482                }
483                $str .= '&nbsp;</td>';
484                break;
485             case 'priority':
486                $priority = $value;
487                $str .= "<th align='right'>$label:&nbsp;</th><td>";
488                $str .= $value . '&nbsp;&nbsp;&nbsp;&nbsp;</td>';
489                break;
490            case 'ip':
491                $str .= "<th align='right'>$label:&nbsp;</th><td>";
492                $str .= $value . '&nbsp;&nbsp;&nbsp;&nbsp;</td>';
493                $ip_set = true;
494                break;
495            default:
496                $str .= "<th align='right'>$label:&nbsp;</th><td>";
497                $str .= $value . '&nbsp;&nbsp;&nbsp;&nbsp;</td>';
498                break;
499        }
500
501    }
502
503    if($ip_set && $priority != 'ip') {
504        $str .= '<caption align="bottom">IP Addresses are matched only where priority is set to IP (and secondary fields are ignored)</caption>';
505    }
506    $str .= "</table>\n";
507    echo "$str</b><br />";
508
509}
510function display_post_data() {
511    $keys =array_keys($_POST);
512
513   $data = "<pre>" . print_r($_POST,true)  . '</pre>';
514   echo $data;
515   $data .= "<pre>" . print_r($keys,true)  . '</pre>';
516   echo $data . DOKU_INC;
517
518   exit;
519}
520?>
521
522
523