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