xref: /plugin/statistics/action.php (revision a5dadbc1009d86c74a281593415744d6d48420ab)
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            '&amp;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->actClean($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    protected function actClean($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