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            '&amp;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