1<?php 2/** 3 * 4 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 5 * @author Andreas Gohr <gohr@cosmocode.de> 6 */ 7 8// must be run within Dokuwiki 9if(!defined('DOKU_INC')) die(); 10 11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); 12require_once(DOKU_PLUGIN . 'action.php'); 13 14class action_plugin_statistics extends DokuWiki_Action_Plugin { 15 16 /** 17 * register the eventhandlers and initialize some options 18 */ 19 function register(Doku_Event_Handler $controller) { 20 global $JSINFO; 21 global $ACT; 22 $JSINFO['act'] = $ACT; 23 24 $controller->register_hook( 25 'IO_WIKIPAGE_WRITE', 26 'BEFORE', 27 $this, 28 'logedits', 29 array() 30 ); 31 $controller->register_hook( 32 'SEARCH_QUERY_FULLPAGE', 33 'AFTER', 34 $this, 35 'logsearch', 36 array() 37 ); 38 $controller->register_hook( 39 'ACTION_ACT_PREPROCESS', 40 'BEFORE', 41 $this, 42 'loglogins', 43 array() 44 ); 45 $controller->register_hook( 46 'AUTH_USER_CHANGE', 47 'AFTER', 48 $this, 49 'logregistration', 50 array() 51 ); 52 $controller->register_hook( 53 'FETCH_MEDIA_STATUS', 54 'BEFORE', 55 $this, 56 'logmedia', 57 array() 58 ); 59 $controller->register_hook( 60 'INDEXER_TASKS_RUN', 61 'AFTER', 62 $this, 63 'loghistory', 64 array() 65 ); 66 } 67 68 /** 69 * @fixme call this in the webbug call 70 */ 71 function putpixel() { 72 global $ID; 73 $url = DOKU_BASE . 'lib/plugins/statistics/log.php?p=' . rawurlencode($ID) . 74 '&r=' . rawurlencode($_SERVER['HTTP_REFERER']) . '&rnd=' . time(); 75 76 echo '<noscript><img src="' . $url . '" width="1" height="1" /></noscript>'; 77 } 78 79 /** 80 * Log page edits actions 81 */ 82 function logedits(Doku_Event $event, $param) { 83 if($event->data[3]) return; // no revision 84 85 if(file_exists($event->data[0][0])) { 86 if($event->data[0][1] == '') { 87 $type = 'D'; 88 } else { 89 $type = 'E'; 90 } 91 } else { 92 $type = 'C'; 93 } 94 /** @var helper_plugin_statistics $hlp */ 95 $hlp = plugin_load('helper', 'statistics'); 96 $hlp->Logger()->log_edit(cleanID($event->data[1] . ':' . $event->data[2]), $type); 97 } 98 99 /** 100 * Log internal search 101 */ 102 function logsearch(Doku_Event $event, $param) { 103 /** @var helper_plugin_statistics $hlp */ 104 $hlp = plugin_load('helper', 'statistics'); 105 $hlp->Logger()->log_search('', $event->data['query'], $event->data['highlight'], 'dokuwiki'); 106 } 107 108 /** 109 * Log login/logouts 110 */ 111 function loglogins(Doku_Event $event, $param) { 112 $type = ''; 113 $act = $this->_act_clean($event->data); 114 if($act == 'logout') { 115 $type = 'o'; 116 } elseif($_SERVER['REMOTE_USER'] && $act == 'login') { 117 if($_REQUEST['r']) { 118 $type = 'p'; 119 } else { 120 $type = 'l'; 121 } 122 } elseif($_REQUEST['u'] && !$_REQUEST['http_credentials'] && !$_SERVER['REMOTE_USER']) { 123 $type = 'f'; 124 } 125 if(!$type) return; 126 127 /** @var helper_plugin_statistics $hlp */ 128 $hlp = plugin_load('helper', 'statistics'); 129 $hlp->Logger()->log_login($type); 130 } 131 132 /** 133 * Log user creations 134 */ 135 function logregistration(Doku_Event $event, $param) { 136 if($event->data['type'] == 'create') { 137 /** @var helper_plugin_statistics $hlp */ 138 $hlp = plugin_load('helper', 'statistics'); 139 $hlp->Logger()->log_login('C', $event->data['params'][0]); 140 } 141 } 142 143 /** 144 * Log media access 145 */ 146 function logmedia(Doku_Event $event, $param) { 147 if($event->data['status'] < 200) return; 148 if($event->data['status'] >= 400) return; 149 if(preg_match('/^\w+:\/\//', $event->data['media'])) return; 150 151 // no size for redirect/not modified 152 if($event->data['status'] >= 300) { 153 $size = 0; 154 } else { 155 $size = @filesize($event->data['file']); 156 } 157 158 /** @var helper_plugin_statistics $hlp */ 159 $hlp = plugin_load('helper', 'statistics'); 160 $hlp->Logger()->log_media( 161 $event->data['media'], 162 $event->data['mime'], 163 !$event->data['download'], 164 $size 165 ); 166 } 167 168 /** 169 * Log the daily page and media counts for the history 170 */ 171 function loghistory(Doku_Event $event, $param) { 172 echo 'Plugin Statistics: started'.DOKU_LF; 173 174 /** @var helper_plugin_statistics $hlp */ 175 $hlp = plugin_load('helper', 'statistics'); 176 177 // check if a history was gathered already today 178 $sql = "SELECT `info` FROM " . $hlp->prefix . "history WHERE `dt` = DATE(NOW())"; 179 $result = $hlp->runSQL($sql); 180 if(is_null($result)) { 181 global $MSG; 182 print_r($MSG); 183 } 184 185 $page_ran = false; 186 $media_ran = false; 187 foreach($result as $row) { 188 if($row['info'] == 'page_count') $page_ran = true; 189 if($row['info'] == 'media_count') $media_ran = true; 190 } 191 192 if($page_ran && $media_ran){ 193 echo 'Plugin Statistics: nothing to do - finished'.DOKU_LF; 194 return; 195 } 196 197 $event->stopPropagation(); 198 $event->preventDefault(); 199 200 if($page_ran) { 201 echo 'Plugin Statistics: logging media'.DOKU_LF; 202 $hlp->Logger()->log_history_media(); 203 } else { 204 echo 'Plugin Statistics: logging pages'.DOKU_LF; 205 $hlp->Logger()->log_history_pages(); 206 } 207 echo 'Plugin Statistics: finished'.DOKU_LF; 208 } 209 210 /** 211 * Pre-Sanitize the action command 212 * 213 * Similar to act_clean in action.php but simplified and without 214 * error messages 215 */ 216 function _act_clean($act) { 217 // check if the action was given as array key 218 if(is_array($act)) { 219 list($act) = array_keys($act); 220 } 221 222 //remove all bad chars 223 $act = strtolower($act); 224 $act = preg_replace('/[^a-z_]+/', '', $act); 225 226 return $act; 227 } 228} 229