source: extensions/whois_online/online.php @ 25171

Last change on this file since 25171 was 24543, checked in by plg, 11 years ago

much much faster algorithm to extract the list of recently displayed photos (avoid array_merge thousands times)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 KB
Line 
1<?php
2
3if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
4global $conf, $conf_whois, $prefixeTable;
5                $path = WHOIS_ONLINE_PATH;
6          $plg_data = implode( '', file($path.'main.inc.php') );
7           if (preg_match("|Version: (.*)|", $plg_data, $val))
8          {
9            $Whois_online_ver = trim($val[1]);
10          }     
11     
12define('WHOIS_ONLINE_VER', $Whois_online_ver); 
13include_once(WHOIS_ONLINE_PATH.'include/wo_functions.inc.php');
14
15define('ONLINE_LEVEL', (100+$conf_whois['Delete level'])/100);
16define('ONLINE_LIMIT', $conf_whois['Obsolete limit']);
17
18
19
20 
21
22
23/* Admin menus are always available */
24add_event_handler('get_admin_plugin_menu_links', 'whois_add_icon' );
25/* On Active */
26if ($conf_whois['Active']) {
27        $conf['Whois Online Update'] = true;
28        add_event_handler('loc_begin_picture', 'whois_online_management');
29        add_event_handler('loc_begin_index', 'whois_online_management');
30        add_event_handler('register_user', 'whois_online_register');
31        if ($conf_whois['Default display'] or (defined('IN_ADMIN') and IN_ADMIN)) 
32                add_event_handler('loc_begin_page_tail', 'whois_default_display' );
33}
34
35
36/*
37                Main process: Analyze, set new values and prepare displayed values.
38               
39                Update on parameter...
40*/
41function whois_online_management()
42{
43        global $user, $conf, $conf_whois, $template, $page, $lang, $lang_info;
44        load_language('plugin.lang', WHOIS_ONLINE_PATH);
45        srand((float)time());
46
47  pwg_debug('*********** start Online_management ***********');
48        if (!isset($conf_whois['Active'])) $conf_whois = whois_online_conf();
49
50        $online = whois_online_get_data();
51
52        $global = $online[0];
53        unset($online[0]);
54        $sid = session_id();
55       
56        // Step 1 - Find the User and/or IP/session_id
57        foreach ($online as $key => $record) {
58                // 1st case: Same IP and same member (Proxy guests are viewed as one)
59                if ($record['IP'] == $_SERVER['REMOTE_ADDR']
60                        and $record['username'] == $user['username'] ) {
61                                $visit = $record;
62                                $v = $key;
63                                break;
64                }
65                // 2nd case: Same session and user (No doubt)
66                if ($record['session_id'] == $sid
67                        and $record['username'] == $user['username'] ) {
68                                $visit = $record; // Maybe a guest
69                                if (!is_a_guest()) $visit['hidden_IP'] = 'true'; // Maybe Proxy or hidden IP
70                                //$visit['IP'] = $_SERVER['REMOTE_ADDR'];
71                                $v = $key;
72                                break;
73                }
74                // 3rd and last case: Same user_id
75                if ($record['user_id'] == $user['id'] and !is_a_guest()) { // new IP and new session
76                                $visit = $record;
77                                $visit['hidden_IP'] = 'true'; /* Or Generic user or the user is using several connections */
78                                //$visit['IP'] = $_SERVER['REMOTE_ADDR'];
79                                $v = $key;
80                                break;
81                }
82        }
83
84        // Step 2 - Assume a new comer
85        if ( !isset($visit) ) {
86                $ctry = '_' . strtoupper( substr(@$_SERVER["HTTP_ACCEPT_LANGUAGE"],6,2) );
87                $visit = Array( 
88                        'IP' => $_SERVER['REMOTE_ADDR'], // First known IP (Is that one true?)
89                        'hidden_IP' => 'false', // supposed a fixed IP
90                        'session_id' => $sid,
91                        'user_id' => $user['id'],
92                        'username' => $user['username'],
93                        'delay' => 0,
94                        'lang' => substr($lang_info['code'],0,2) . $ctry,
95                        'permanent' => 'false', // False: delete after 72 Hours / True: delete after 90 days
96                        'last_access' => time(), // Last access by this user
97                        'elm_ids' => array_fill(0, 10, 0), // 10 last minutes + Last reference minute
98                        'cat_ids' => array_fill(0, 12, 0), // 12 ranges (of 5 minutes) + ref
99                        'tag_ids' => array_fill(0, 24, 0), // 24 hours + ref
100                        'sch_ids' => array_fill(0, 14, 0), // 14 days + ref
101                        'date' => date('Y-m-d'), // Futur usage
102                        'elm_hits' => 0, 'pag_hits' => 0, // elements hits and pages hits by this user
103                        'first_access_date' => date('Y-m-d'), // First access by this user
104                        'dates' => Array(), // 5 last access dates
105                );
106                $online[] = $visit;
107                $v = count($online);
108        }
109
110        // Step 3 - Monitor this access
111        $base = script_basename();
112        // Picture page
113        if (isset($page['image_id']) and $base == 'picture') {
114                whois_online_track($visit['elm_ids'], $page['image_id'],$visit['dates']);
115                if (isset($page['tags']))
116                whois_online_track($visit['tag_ids'], $page['image_id'],$visit['dates']);
117                if (isset($page['search']))
118                whois_online_track($visit['sch_ids'], $page['image_id'],$visit['dates']);
119                $visit['elm_hits']++;
120                $global['elm_hits']++;
121        }
122        // Category page
123        if (isset($page['category']['id']) and $base == 'index')
124                whois_online_track($visit['cat_ids'], $page['category']['id'],$visit['dates']);
125        // Page index
126        if (!isset($page['category']['id']) and !isset($page['image_id']))
127                whois_online_track($visit['cat_ids'], '' ,$visit['dates']);
128        $visit['pag_hits']++;
129        $global['pag_hits']++;
130
131        // Step 4 - Identify current range
132        $current = floor(time() / 60);                  // minutes for Unix time origin
133        $minute = $current % 10;                                                // (0-9) current minute
134        $five = floor($current / 5);    // (0-11) last 5 minutes range
135        $hour = floor($current / 60);   // (0-11) last hours
136        $day = floor($current / 1440); // (0-13) last days
137        if (isset($global['elm_ids'][10])) $old = $global['elm_ids'][10]; // previous minute (last one, or maybe 60 minutes ago or more).
138        else $old = $current; /* Only the first time or prevent wrong changes */
139
140        // Step 5 - Hits by range
141        if ($current != $old) {
142                $global['elm_ids'][11] = $global['elm_ids'][$minute];
143                $raz = min($current-$old, 10);
144        // 5.1 - $global['elm_ids'] ( hits by minute range )
145                for ($i=0;$i<$raz;$i++) {
146                        $global['elm_ids'][($minute+10-$i)%10] = 0;
147                }
148        // 5.2 - $global['cat_ids'] ( hits by 5 minutes range )
149                if (isset($global['cat_ids'][12])) $oldfive = $global['cat_ids'][12];
150                else $oldfive = floor($old / 5);
151                $raz = min($five - $oldfive, 12);
152                for ($i=0;$i<$raz;$i++) {
153                        $global['cat_ids'][($five+12-$i)%12] = 0; // Reset in backside
154                }
155        // 5.3 - $global['tag_ids'] (hits by hours )
156                if (count($global['tag_ids'])<25) $global['tag_ids'] = array_fill(0, 24, 0);
157                if (isset($global['tag_ids'][24])) $oldhour = $global['tag_ids'][24];
158                else $oldhour = floor($old / 60);
159                $raz = min($hour - $oldhour, 24);
160                for ($i=0;$i<$raz;$i++) {
161                        $global['tag_ids'][($hour+24-$i)%24] = 0; // Reset in backside
162                }
163        // 5.4 - $global['sch_ids'] ( hits by days )
164                if (isset($global['sch_ids'][14])) $oldday = $global['sch_ids'][14];
165                else $oldday = floor($old / 1440);
166                $raz = min($day - $oldday, 14);
167                for ($i=0;$i<$raz;$i++) {
168                        $global['sch_ids'][($day+14-$i)%14] = 0; // Reset in backside
169                }
170        }
171        $global['elm_ids'][$minute]++;
172        $global['cat_ids'][$five%12]++;
173        $global['tag_ids'][$hour%12]++;
174        $global['sch_ids'][$day%14]++;
175  // !!! WARNING  !!! WARNING !!! WARNING !!! WARNING !!!
176        $global['elm_ids'][10] = $current; // reference minute has changed
177        $global['cat_ids'][12] = $five;
178        $global['tag_ids'][24] = $hour;
179        $global['sch_ids'][14] = $day;
180  // !!! WARNING  !!! WARNING !!! WARNING !!! WARNING !!!
181
182        // 5.5 - Add in previous
183  if (!isset($global['any_previous'])) {
184                pwg_query('ALTER TABLE ' . WHOIS_ONLINE_TABLE . 
185                        ' ADD `same_previous` VARCHAR( 255 ) NOT NULL DEFAULT \'\'  AFTER `country`;');
186                pwg_query('ALTER TABLE ' . WHOIS_ONLINE_TABLE . 
187                        ' ADD `any_previous` VARCHAR( 255 ) NOT NULL DEFAULT \'\'  AFTER `country`;');
188                pwg_query('ALTER TABLE ' . WHOIS_ONLINE_TABLE . 
189                        ' ADD `user_agent` VARCHAR( 160 ) NOT NULL DEFAULT \'\'  AFTER `country`;');
190        }
191
192        $antiaspi = array(
193    'diff' => '20 pages in 00:00:10' , // Banned for 20 access in 10 seconds or less
194    'same' => '15 pages in 00:00:30' , // Banned for 15 access on the same page in 30 seconds or less
195    'banned during' => '23:59:59' ,    // Banned time hh:mm:ss or any valid MySQL datetime expression 'YYYY-MM-DD HH:MM:SS'
196    'only guest' => true ,             // True, registred members won't be banned
197    'only picture' => false ,          // True, Check only on picture pages
198    'allowed ip' => array()            // Allowed IP array (Bots, or your fixed IP)
199  );
200  if (isset($conf['antiaspi'])) $antiaspi = array_merge($antiaspi, $conf['antiaspi']);
201
202        // For AntiAspi follow ANY PREVIOUS access
203        $access = '0:';
204        list($max_any, $maxtext) = explode(' pages in ', $antiaspi['diff']);
205        $maxtime = whois_online_duration($maxtext);
206        $prev='';
207        $previous = (isset($visit['any_previous'])) ? explode(' ', $visit['any_previous']):Array();
208        foreach ($previous as $v) {
209                $old = explode(':', $v);
210                $old[0] += $visit['delay']; 
211                if ($old[0]<$maxtime) $prev .= $old[0].': ';
212        }
213        $prev = $access . ' ' . $prev;
214        $prev = substr($prev, 0, -2);
215        $visit['any_previous'] = $prev;
216        // For AntiAspi follow ANY SAME PICTURE access
217        $access = '0:';
218        $same_elem = (isset($page['image_id'])) ? $page['image_id']:'0';
219        list($max_same, $maxtext) = explode(' pages in ', $antiaspi['same']);
220        $maxtime = whois_online_duration($maxtext);
221        $access .= $same_elem . ':';
222        $prev='';
223        $previous = (isset($visit['same_previous'])) ? explode(' ', $visit['same_previous']):Array();
224        foreach ($previous as $v) {
225                $old = explode(':', $v);
226                $old[0] += $visit['delay'];
227                if ($old[0]<$maxtime and $old[1]==$same_elem) $prev .= $old[0].':'.$old[1].': ';
228        }
229        $prev = $access . ' ' . $prev;
230        $prev = substr($prev, 0, -2);
231        $visit['same_previous'] = $prev;
232       
233        // Check limits of $visit['any_previous'] and $visit['same_previous']
234        // by 256 characters
235        // by $max_any and by $max_same
236        while (strlen($visit['any_previous'])>256) {
237          $previous = explode(' ',$visit['any_previous']);
238                $oldest = array_pop($previous);
239                $visit['any_previous'] = implode(' ', $previous);
240        }
241        $ctr_any = count(explode(' ',$visit['any_previous']));
242        while (strlen($visit['same_previous'])>256) {
243          $previous = explode(' ',$visit['same_previous']);
244                $oldest = array_pop($previous);
245                $visit['same_previous'] = implode(' ', $previous);
246        }
247        $ctr_same = count(explode(' ',$visit['same_previous']));
248       
249        $visit['user_agent'] = substr($_SERVER['HTTP_USER_AGENT'],0,160);
250        $Vip =& $visit['IP'];
251        $visit['Allowed_SE'] = false;
252  if (!empty($antiaspi['allowed ip']))
253  {
254    $allowed_ips = str_replace(array('.', '%'), array('\.', '.*?'), $antiaspi['allowed ip']);
255    foreach ($allowed_ips as $ip)
256    {
257      if (preg_match("#" . $ip . "#", $Vip)) { $visit['Allowed_SE'] = true; break; }
258    }
259  }
260       
261        // Step 6 - Update (on Conf_Update and trace) and send trace to determine global tracing or not
262        $dtrace = 0;
263        if ($user['status'] == 'admin') $dtrace += $conf_whois['Administrators'];
264        elseif ($user['status'] == 'webmaster') $dtrace += $conf_whois['Webmasters'];
265        else $dtrace = 2;
266        if ($conf['Whois Online Update'] and $dtrace > 0) whois_online_update($global, $visit, $dtrace);
267
268        // Step 7 - Find your recent visits (These image_ids are presumely authorized)
269        $my_ids = $visit['elm_ids'];
270        sort($my_ids);
271        unset($my_ids[0]);
272        $url_visited = (count($my_ids)>0) ? make_index_url(array('list' => $my_ids)).'&amp;review':'';
273
274        // Step 8 - Guest count and Member list
275        $h24 = 0; $h1 = 0; $guest = 0;
276        $list = array();
277        $elm = array(); $excl = array(); // Get images_ids from all and from the current visitor
278        foreach ($online as $k => $monit)
279        {
280                if ($user['id']==$monit['user_id']) $excl = $monit['elm_ids'];
281                // else $elm = array_merge($elm, $monit['elm_ids']);
282    else
283    {
284      foreach ($monit['elm_ids'] as $id)
285      {
286        $elm[$id] = 1;
287      }
288    }
289                if ($monit['delay'] <= (24*3600)) $h24++;
290                if ($monit['delay'] <= 3600) $h1++;
291                // Less than 5 minutes: users are considered as still online...
292                if ($monit['delay'] <= 300) {
293                        if ($monit['user_id'] == $conf['guest_id']) $guest++;
294                        else $list[] = $monit['username'];
295                }
296        }
297  $elm = array_keys($elm);
298        // The first (and current) access are not recorded in $online
299        // As visitor you are not expecting your access to be already counted: Ok that the case
300        // but you are expecting to see you as a member in the member list if you are: and there it is
301        if ($visit['user_id'] != $conf['guest_id'] ) $list[] = $visit['username'];
302        $list = array_unique($list);
303       
304        if (count($list) > $conf_whois['Users']['max']) {
305                $conf_whois['Users']['max'] = count($list);
306                $conf_whois['Users']['When'] = time();
307                $conf['Whois Online'] = serialize($conf_whois);
308                pwg_query('REPLACE INTO ' . CONFIG_TABLE . " (param,value,comment)
309    VALUES ('Whois Online','". $conf['Whois Online'] ."','Whois Online configuration');");
310        }
311
312        // Step 9 - Review pictures viewed by others (all images except yours)
313        $elm = array_diff( array_unique($elm), $excl );
314        shuffle($elm);
315        $elm = array_slice($elm,0,($conf['top_number']+50));
316        sort($elm);
317        array_shift($elm);
318        $elm[] = 0; // Check if authorized pictures
319        $query = 'SELECT DISTINCT(image_id)
320  FROM '.IMAGE_CATEGORY_TABLE.'
321    INNER JOIN '.IMAGES_TABLE.' ON id = image_id
322  WHERE image_id IN ('.implode(',', $elm ).')
323    '.get_sql_condition_FandF(
324      array(
325          'forbidden_categories' => 'category_id',
326          'visible_categories' => 'category_id',
327          'visible_images' => 'id'
328        ), "\n  AND") . ';';
329        $ids = array_from_query($query, 'image_id');
330        shuffle($ids);
331        $ids = array_slice($ids, 0, $conf['top_number']); // Keep some
332        $url_someothers = (isset($ids[0])) ? make_index_url(array('list' => $ids)).'&amp;others':'';
333
334        // Random page title change
335        $url_type = pwg_get_session_var('whois_url_type', ''); /* previous review or others */
336        $list_ids = pwg_get_session_var('whois_list_ids', ''); /* previous list/xx,yy,zz, ... */
337        $list_section = (isset($page['section']) and $page['section'] == 'list') ? true:false;
338        $same_ids = (isset($page['list']) and $page['list'] == $list_ids) ? true:false;
339        if ($list_section and isset($_GET['review'])) {
340                $url_type = 'Whois_review';
341                $same_ids = true;
342        }
343        if ($list_section and isset($_GET['others'])) {
344                $url_type = 'Whois_others';
345                $same_ids = true;
346        }
347        if ($list_section and $same_ids and isset($page['list'])) $list_ids = $page['list'];
348        else $url_type = ''; // Not the same list
349        pwg_set_session_var('whois_list_ids', $list_ids);
350        pwg_set_session_var('whois_url_type', $url_type);
351        if ($url_type != '' and $list_section)
352  $page['title'] = '<a href="'.duplicate_index_url(array('start'=>0)).'">'
353                    .l10n($url_type).'</a>';
354
355       
356        // Step 10 - Prepare data to display
357        $yesterday = ($day+13) % 14;
358        $template->assign('Whois', array(
359                'Total' => $global['pag_hits'],
360                'Image' => $global['elm_hits'],
361                'Other' => ($global['pag_hits']-$global['elm_hits']),
362                'Current_minute' => $global['elm_ids'][$minute],
363                'Previous_minute' => $global['elm_ids'][($minute+9) % 10],
364                'Current_5mins' => $global['elm_ids'][$minute]
365                                                                        + $global['elm_ids'][($minute+9) % 10]
366                                                                        + $global['elm_ids'][($minute+8) % 10]
367                                                                        + $global['elm_ids'][($minute+7) % 10]
368                                                                        + $global['elm_ids'][($minute+6) % 10],
369                'Current_10mins' => array_sum(array_slice($global['elm_ids'],0,10)),
370                'Current_hour' => array_sum(array_slice($global['cat_ids'],0,12)),
371                'Current_24h' => array_sum(array_slice($global['tag_ids'],0,24)),
372                'Yesterday' => $global['sch_ids'][$yesterday],
373                'Users_Last_day' => $h24,
374                'Users_Last_hour' => $h1,
375                'Guests' => $guest,
376                'Online' => $list,
377                'Review_url' => $url_someothers,
378                'Their_ids' => $ids,
379                'Seen_url' => $url_visited,
380                'My_ids' => $my_ids,
381                'Slideshow' => isset($_GET['slideshow']) ? true:false,
382        ));
383        $template->assign('Online', $global );
384
385        pwg_debug('end Online_management');
386}
387?>
Note: See TracBrowser for help on using the repository browser.