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