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