1<?php 2// 3// DokuWiki Onlinenumber Plugin 4// 5// 6// Original source of this plugin is PukiWiki. 7// Ported by Hokkaidoperson <dosankomali@yahoo.co.jp> 8// 9// 10// Original Licenses of this plugin: 11// 12// $Id: online.inc.php,v 1.12 2007/02/10 06:21:53 henoheno Exp $ 13// Copyright (C) 14// 2002-2005, 2007 PukiWiki Developers Team 15// 2001-2002 Originally written by yu-ji 16// License: GPL v2 or (at your option) any later version 17// 18// Online plugin -- Just show the number 'users-on-line' 19 20// must be run within Dokuwiki 21if(!defined('DOKU_INC')) die(); 22 23class syntax_plugin_onlinenumber extends DokuWiki_Syntax_Plugin { 24 25 function getType(){ 26 return 'substition'; 27 } 28 29 function getSort(){ 30 return 160; 31 } 32 33 34 // Internal functions 35 36 // Check I am already online (recorded and not time-out) 37 // & $count == Number of online users 38 function plugin_online_check_online(& $count, $host = '') 39 { 40 if (! touch(PLUGIN_ONLINE_USER_LIST)) return FALSE; 41 42 // Open 43 $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r'); 44 if ($fp == FALSE) return FALSE; 45 set_file_buffer($fp, 0); 46 47 // Init 48 $count = 0; 49 $found = FALSE; 50 $matches = array(); 51 52 flock($fp, LOCK_SH); 53 54 // Read 55 while (! feof($fp)) { 56 $line = fgets($fp, 512); 57 if ($line === FALSE) continue; 58 59 // Ignore invalid-or-outdated lines 60 if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $line, $matches) || 61 ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME || 62 $matches[2] > UTIME) continue; 63 64 ++$count; 65 if (! $found && $matches[1] == $host) $found = TRUE; 66 } 67 68 flock($fp, LOCK_UN); 69 70 if(! fclose($fp)) return FALSE; 71 72 if (! $found && $host != '') ++$count; // About you 73 74 return $found; 75 } 76 77 // Cleanup outdated records, Add/Replace new record, Return the number of 'users in N seconds' 78 // NOTE: Call this when plugin_online_check_online() returnes FALSE 79 function plugin_online_sweep_records($host = '') 80 { 81 // Open 82 $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r+'); 83 if ($fp == FALSE) return FALSE; 84 set_file_buffer($fp, 0); 85 86 flock($fp, LOCK_EX); 87 88 // Read to check 89 $lines = @file(PLUGIN_ONLINE_USER_LIST); 90 if ($lines === FALSE) $lines = array(); 91 92 // Need modify? 93 $line_count = $count = count($lines); 94 $matches = array(); 95 $dirty = FALSE; 96 for ($i = 0; $i < $line_count; $i++) { 97 if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $lines[$i], $matches) || 98 ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME || 99 $matches[2] > UTIME || 100 $matches[1] == $host) { 101 unset($lines[$i]); // Invalid or outdated or invalid date 102 --$count; 103 $dirty = TRUE; 104 } 105 } 106 if ($host != '' ) { 107 // Add new, at the top of the record 108 array_unshift($lines, strtr($host, "\n", '') . '|' . UTIME . "\n"); 109 ++$count; 110 $dirty = TRUE; 111 } 112 113 if ($dirty) { 114 // Write 115 if (! ftruncate($fp, 0)) return FALSE; 116 rewind($fp); 117 fputs($fp, join('', $lines)); 118 } 119 120 flock($fp, LOCK_UN); 121 122 if(! fclose($fp)) return FALSE; 123 124 return $count; // Number of lines == Number of users online 125 } 126 127 //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) 128 //The texts following the number of online are not required (If entered just {{onlinenumber}} , this will return only the number) 129 130 function connectTo($mode) { 131 $this->Lexer->addSpecialPattern('\{\{onlinenumber[^}]*\}\}',$mode,'plugin_onlinenumber'); 132 } 133 134 135 function handle($match, $state, $pos, Doku_Handler $handler){ 136 137 return explode('|', substr($match, strlen('{{onlinenumber|'), -2)); 138 139 } 140 141 function render($mode, Doku_Renderer $renderer, $data) { 142 define('PLUGIN_ONLINE_TIMEOUT', $this->getConf('onlineseconds')); // Count users in N seconds 143 144 // List of 'IP-address|last-access-time(seconds)' 145 define('PLUGIN_ONLINE_USER_LIST', DOKU_PLUGIN . 'onlinenumber/user.dat'); 146 147 // Regex of 'IP-address|last-access-time(seconds)' 148 define('PLUGIN_ONLINE_LIST_REGEX', '/^([^\|]+)\|([0-9]+)$/'); 149 150 // UTIME ... universal time 151 define('UTIME', time() - date('Z')); 152 153 154 // Main process 155 static $count, $result, $base; 156 157 if (! isset($count)) { 158 if (isset($_SERVER['REMOTE_ADDR'])) { 159 $host = & $_SERVER['REMOTE_ADDR']; 160 } else { 161 $host = ''; 162 } 163 164 // Try read 165 if ($this->plugin_online_check_online($count, $host)) { 166 $result = TRUE; 167 } else { 168 // Write 169 $result = $this->plugin_online_sweep_records($host); 170 } 171 } 172 173 if ($result) { // Integer 174 if ($count == 1) { 175 $renderer->doc .= htmlspecialchars($count) .htmlspecialchars($data[0]); 176 } else { 177 $renderer->doc .= htmlspecialchars($count) .htmlspecialchars($data[1]); 178 } 179 } else { 180 if (! isset($base)) $base = basename(PLUGIN_ONLINE_USER_LIST); 181 $error = $this->getLang('err1') . $base . $this->getLang('err2'); 182 $renderer->doc .= htmlspecialchars($error); // String 183 } 184 185 } 186 187 188} 189