xref: /plugin/statistics/action.php (revision a8acb244f011a1b8bd9a22373e14f2819297c46f)
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            '&amp;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