// // // Original Licenses of this plugin: // // $Id: online.inc.php,v 1.12 2007/02/10 06:21:53 henoheno Exp $ // Copyright (C) // 2002-2005, 2007 PukiWiki Developers Team // 2001-2002 Originally written by yu-ji // License: GPL v2 or (at your option) any later version // // Online plugin -- Just show the number 'users-on-line' // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); class syntax_plugin_onlinenumber extends DokuWiki_Syntax_Plugin { function getType(){ return 'substition'; } function getSort(){ return 160; } // Internal functions // Check I am already online (recorded and not time-out) // & $count == Number of online users function plugin_online_check_online(& $count, $host = '') { if (! touch(PLUGIN_ONLINE_USER_LIST)) return FALSE; // Open $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r'); if ($fp == FALSE) return FALSE; set_file_buffer($fp, 0); // Init $count = 0; $found = FALSE; $matches = array(); flock($fp, LOCK_SH); // Read while (! feof($fp)) { $line = fgets($fp, 512); if ($line === FALSE) continue; // Ignore invalid-or-outdated lines if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $line, $matches) || ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME || $matches[2] > UTIME) continue; ++$count; if (! $found && $matches[1] == $host) $found = TRUE; } flock($fp, LOCK_UN); if(! fclose($fp)) return FALSE; if (! $found && $host != '') ++$count; // About you return $found; } // Cleanup outdated records, Add/Replace new record, Return the number of 'users in N seconds' // NOTE: Call this when plugin_online_check_online() returnes FALSE function plugin_online_sweep_records($host = '') { // Open $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r+'); if ($fp == FALSE) return FALSE; set_file_buffer($fp, 0); flock($fp, LOCK_EX); // Read to check $lines = @file(PLUGIN_ONLINE_USER_LIST); if ($lines === FALSE) $lines = array(); // Need modify? $line_count = $count = count($lines); $matches = array(); $dirty = FALSE; for ($i = 0; $i < $line_count; $i++) { if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $lines[$i], $matches) || ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME || $matches[2] > UTIME || $matches[1] == $host) { unset($lines[$i]); // Invalid or outdated or invalid date --$count; $dirty = TRUE; } } if ($host != '' ) { // Add new, at the top of the record array_unshift($lines, strtr($host, "\n", '') . '|' . UTIME . "\n"); ++$count; $dirty = TRUE; } if ($dirty) { // Write if (! ftruncate($fp, 0)) return FALSE; rewind($fp); fputs($fp, join('', $lines)); } flock($fp, LOCK_UN); if(! fclose($fp)) return FALSE; return $count; // Number of lines == Number of users online } //Syntax: {{onlinenumber|texts following the number of online (when the number is 1)|texts following the number of online (when the number is 2 or more) //The texts following the number of online are not required (If entered just {{onlinenumber}} , this will return only the number) function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{onlinenumber[^}]*\}\}',$mode,'plugin_onlinenumber'); } function handle($match, $state, $pos, Doku_Handler $handler){ return explode('|', substr($match, strlen('{{onlinenumber|'), -2)); } function render($mode, Doku_Renderer $renderer, $data) { define('PLUGIN_ONLINE_TIMEOUT', $this->getConf('onlineseconds')); // Count users in N seconds // List of 'IP-address|last-access-time(seconds)' define('PLUGIN_ONLINE_USER_LIST', DOKU_PLUGIN . 'onlinenumber/user.dat'); // Regex of 'IP-address|last-access-time(seconds)' define('PLUGIN_ONLINE_LIST_REGEX', '/^([^\|]+)\|([0-9]+)$/'); // UTIME ... universal time define('UTIME', time() - date('Z')); // Main process static $count, $result, $base; if (! isset($count)) { if (isset($_SERVER['REMOTE_ADDR'])) { $host = & $_SERVER['REMOTE_ADDR']; } else { $host = ''; } // Try read if ($this->plugin_online_check_online($count, $host)) { $result = TRUE; } else { // Write $result = $this->plugin_online_sweep_records($host); } } if ($result) { // Integer if ($count == 1) { $renderer->doc .= htmlspecialchars($count) .htmlspecialchars($data[0]); } else { $renderer->doc .= htmlspecialchars($count) .htmlspecialchars($data[1]); } } else { if (! isset($base)) $base = basename(PLUGIN_ONLINE_USER_LIST); $error = $this->getLang('err1') . $base . $this->getLang('err2'); $renderer->doc .= htmlspecialchars($error); // String } } }