1<?php
2
3class admin_plugin_loglog extends DokuWiki_Admin_Plugin
4{
5    /**
6     * @var \helper_plugin_loglog_logging
7     */
8    protected $logHelper;
9
10    /**
11     * @var \helper_plugin_loglog_main
12     */
13    protected $mainHelper;
14
15    /**
16     * @var string
17     */
18    protected $filter = '';
19
20    /** @inheritDoc */
21    public function forAdminOnly()
22    {
23        return false;
24    }
25
26    /** @inheritDoc */
27    public function getMenuSort()
28    {
29        return 141;
30    }
31
32    public function __construct()
33    {
34        $this->logHelper = $this->loadHelper('loglog_logging');
35        $this->mainHelper = $this->loadHelper('loglog_main');
36
37        global $INPUT;
38        $this->filter = $INPUT->str('filter');
39    }
40
41
42    /** @inheritDoc */
43    public function html()
44    {
45        global $ID, $INPUT, $conf, $lang;
46        $now = time();
47        $go = isset($_REQUEST['time']) ? intval($_REQUEST['time']) : $now;
48        $min = $go - (7 * 24 * 60 * 60);
49        $max = $go;
50
51        $past = $now - $go > 60 * 60 * 5;
52        if ($past) {
53            $next = $max + (7 * 24 * 60 * 60);
54            if ($now - $next < 60 * 60 * 5) {
55                $next = $now;
56            }
57        }
58
59        $time = $INPUT->str('time') ?: $now;
60
61        // alternative date format?
62        $dateFormat = $this->getConf('admin_date_format') ?: $conf['dformat'];
63
64        echo $this->locale_xhtml('intro');
65
66        $form = new dokuwiki\Form\Form(['method'=>'GET']);
67        $form->setHiddenField('do', 'admin');
68        $form->setHiddenField('page', 'loglog');
69        $form->setHiddenField('time', $time);
70        $form->addDropdown(
71            'filter',
72            [
73                '' => '',
74                'auth_ok' => $this->getLang('filter_auth_ok'),
75                'auth_error' => $this->getLang('filter_auth_error'),
76                'admin' => $this->getLang('filter_admin'),
77                'other' => $this->getLang('filter_other')
78            ]
79        );
80        $form->addButton('submit', $this->getLang('submit'))->attr('type','submit');
81        echo $form->toHTML();
82
83        echo '<p>' . $this->getLang('range') . ' ' . strftime($dateFormat, $min) .
84            ' - ' . strftime($dateFormat, $max) . '</p>';
85
86        echo '<table class="inline loglog">';
87        echo '<tr>';
88        echo '<th>' . $this->getLang('date') . '</th>';
89        echo '<th>' . $this->getLang('ip') . '</th>';
90        echo '<th>' . $lang['user'] . '</th>';
91        echo '<th>' . $this->getLang('action') . '</th>';
92        echo '<th>'. $this->getLang('data') . '</th>';
93        echo '</tr>';
94
95        $lines = $this->logHelper->readLines($min, $max);
96        $lines = array_reverse($lines);
97
98        foreach ($lines as $line) {
99            if (!$line['user']) continue;
100
101            $logType = $this->mainHelper->getLogTypeFromMsg($line['msg']);
102
103            if ($this->filter && $this->filter !== '' && $this->filter!== $logType) {
104                continue;
105            }
106
107            if ($line['msg'] == 'logged off') {
108                $line['msg'] = $this->getLang('off');
109                $class = 'off';
110            } elseif ($line['msg'] == 'logged in permanently') {
111                $line['msg'] = $this->getLang('in');
112                $class = 'perm';
113            } elseif ($line['msg'] == 'logged in temporarily') {
114                $line['msg'] = $this->getLang('tin');
115                $class = 'temp';
116            } elseif ($line['msg'] == 'failed login attempt') {
117                $line['msg'] = $this->getLang('fail');
118                $class = 'fail';
119            } elseif ($line['msg'] == 'has been automatically logged off') {
120                $line['msg'] = $this->getLang('autologoff');
121                $class = 'off';
122            } else {
123                $line['msg'] = hsc($line['msg']);
124                if (strpos($line['msg'], 'logged off') !== false) {
125                    $class = 'off';
126                } elseif (strpos($line['msg'], 'logged in permanently') !== false) {
127                    $class = 'perm';
128                } elseif (strpos($line['msg'], 'logged in') !== false) {
129                    $class = 'temp';
130                } elseif (strpos($line['msg'], 'failed') !== false) {
131                    $class = 'fail';
132                } else {
133                    $class = 'unknown';
134                }
135            }
136
137            echo '<tr>';
138            echo '<td>' . strftime($dateFormat, $line['dt']) . '</td>';
139            echo '<td>' . hsc($line['ip']) . '</td>';
140            echo '<td>' . hsc($line['user']) . '</td>';
141            echo '<td><span class="loglog_' . $class . '">' . $line['msg'] . '</span></td>';
142            echo '<td>';
143            if ($line['data']) {
144                // logs contain single-line JSON data, so we have to decode and encode it again for pretty print
145                echo '<pre>' . json_encode(json_decode($line['data']), JSON_PRETTY_PRINT) . '</pre>';
146            }
147            echo '</td>';
148            echo '</tr>';
149        }
150
151        echo '</table>';
152
153        echo '<div class="pagenav">';
154        if ($past) {
155            echo '<div class="pagenav-prev">';
156            echo html_btn('newer',
157                $ID,
158                "p",
159                ['do' => 'admin', 'page' => 'loglog', 'time' => $next, 'filter' => $this->filter]
160            );
161            echo '</div>';
162        }
163
164        echo '<div class="pagenav-next">';
165        echo html_btn('older',
166            $ID,
167            "n",
168            ['do' => 'admin', 'page' => 'loglog', 'time' => $min, 'filter' => $this->filter]
169        );
170        echo '</div>';
171        echo '</div>';
172
173    }
174}
175