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