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 */ 12class action_plugin_statistics extends ActionPlugin 13{ 14 /** 15 * register the eventhandlers and initialize some options 16 */ 17 public function register(EventHandler $controller) 18 { 19 global $JSINFO; 20 global $ACT; 21 $JSINFO['act'] = $ACT; 22 23 // FIXME new save event might be better: 24 $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'logedits', []); 25 $controller->register_hook('SEARCH_QUERY_FULLPAGE', 'AFTER', $this, 'logsearch', []); 26 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'loglogins', []); 27 $controller->register_hook('AUTH_USER_CHANGE', 'AFTER', $this, 'logregistration', []); 28 $controller->register_hook('FETCH_MEDIA_STATUS', 'BEFORE', $this, 'logmedia', []); 29 $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'loghistory', []); 30 } 31 32 /** 33 * @fixme call this in the webbug call 34 */ 35 public function putpixel() 36 { 37 global $ID, $INPUT; 38 $url = DOKU_BASE . 'lib/plugins/statistics/log.php?p=' . rawurlencode($ID) . 39 '&r=' . rawurlencode($INPUT->server->str('HTTP_REFERER')) . '&rnd=' . time(); 40 41 echo '<noscript><img alt="" src="' . $url . '" width="1" height="1" /></noscript>'; 42 } 43 44 /** 45 * Log page edits actions 46 */ 47 public function logedits(Event $event, $param) 48 { 49 if ($event->data[3]) return; // no revision 50 51 if (file_exists($event->data[0][0])) { 52 if ($event->data[0][1] == '') { 53 $type = 'D'; 54 } else { 55 $type = 'E'; 56 } 57 } else { 58 $type = 'C'; 59 } 60 /** @var helper_plugin_statistics $hlp */ 61 $hlp = plugin_load('helper', 'statistics'); 62 $hlp->getLogger()->logEdit($event->data[1] . ':' . $event->data[2], $type); 63 } 64 65 /** 66 * Log internal search 67 */ 68 public function logsearch(Event $event, $param) 69 { 70 /** @var helper_plugin_statistics $hlp */ 71 $hlp = plugin_load('helper', 'statistics'); 72 $hlp->getLogger()->logSearch($event->data['query'], $event->data['highlight']); 73 } 74 75 /** 76 * Log login/logouts 77 */ 78 public function loglogins(Event $event, $param) 79 { 80 global $INPUT; 81 82 $type = ''; 83 $act = $this->actClean($event->data); 84 if ($act == 'logout') { 85 $type = 'o'; 86 } elseif ($INPUT->server->str('REMOTE_USER') && $act == 'login') { 87 if ($INPUT->str('r')) { 88 $type = 'p'; 89 } else { 90 $type = 'l'; 91 } 92 } elseif ($INPUT->str('u') && !$INPUT->str('http_credentials') && !$INPUT->server->str('REMOTE_USER')) { 93 $type = 'f'; 94 } 95 if (!$type) return; 96 97 /** @var helper_plugin_statistics $hlp */ 98 $hlp = plugin_load('helper', 'statistics'); 99 $hlp->getLogger()->logLogin($type); 100 } 101 102 /** 103 * Log user creations 104 */ 105 public function logregistration(Event $event, $param) 106 { 107 if ($event->data['type'] == 'create') { 108 /** @var helper_plugin_statistics $hlp */ 109 $hlp = plugin_load('helper', 'statistics'); 110 $hlp->getLogger()->logLogin('C', $event->data['params'][0]); 111 } 112 } 113 114 /** 115 * Log media access 116 */ 117 public function logmedia(Event $event, $param) 118 { 119 if ($event->data['status'] < 200) return; 120 if ($event->data['status'] >= 400) return; 121 if (preg_match('/^\w+:\/\//', $event->data['media'])) return; 122 123 // no size for redirect/not modified 124 if ($event->data['status'] >= 300) { 125 $size = 0; 126 } else { 127 $size = @filesize($event->data['file']); 128 } 129 130 /** @var helper_plugin_statistics $hlp */ 131 $hlp = plugin_load('helper', 'statistics'); 132 $hlp->getLogger()->logMedia( 133 $event->data['media'], 134 $event->data['mime'], 135 !$event->data['download'], 136 $size 137 ); 138 } 139 140 /** 141 * Log the daily page and media counts for the history 142 */ 143 public function loghistory(Event $event, $param) 144 { 145 echo 'Plugin Statistics: started' . DOKU_LF; 146 147 /** @var helper_plugin_statistics $hlp */ 148 $hlp = plugin_load('helper', 'statistics'); 149 $db = $hlp->getDB(); 150 151 // check if a history was gathered already today 152 $result = $db->queryAll( 153 "SELECT info FROM history WHERE date(dt) = date('now')" 154 ); 155 156 $page_ran = false; 157 $media_ran = false; 158 foreach ($result as $row) { 159 if ($row['info'] == 'page_count') $page_ran = true; 160 if ($row['info'] == 'media_count') $media_ran = true; 161 } 162 163 if ($page_ran && $media_ran) { 164 echo 'Plugin Statistics: nothing to do - finished' . DOKU_LF; 165 return; 166 } 167 168 $event->stopPropagation(); 169 $event->preventDefault(); 170 171 if ($page_ran) { 172 echo 'Plugin Statistics: logging media' . DOKU_LF; 173 $hlp->getLogger()->logHistoryMedia(); 174 } else { 175 echo 'Plugin Statistics: logging pages' . DOKU_LF; 176 $hlp->getLogger()->logHistoryPages(); 177 } 178 echo 'Plugin Statistics: finished' . DOKU_LF; 179 } 180 181 /** 182 * Pre-Sanitize the action command 183 * 184 * Similar to act_clean in action.php but simplified and without 185 * error messages 186 */ 187 protected function actClean($act) 188 { 189 // check if the action was given as array key 190 if (is_array($act)) { 191 [$act] = array_keys($act); 192 } 193 194 //remove all bad chars 195 $act = strtolower($act); 196 $act = preg_replace('/[^a-z_]+/', '', $act); 197 198 return $act; 199 } 200} 201