1<?php
2
3use dokuwiki\Logger;
4
5/**
6 * DokuWiki Plugin logviewer (Admin Component)
7 *
8 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
9 * @author  Andreas Gohr <andi@splitbrain.org>
10 */
11class admin_plugin_logviewer extends DokuWiki_Admin_Plugin
12{
13
14    protected $facilities;
15    protected $facility;
16    protected $date;
17
18    /** @inheritDoc */
19    public function forAdminOnly()
20    {
21        return true;
22    }
23
24    /** @inheritDoc */
25    public function handle()
26    {
27        global $INPUT;
28
29        $this->facilities = $this->getFacilities();
30        $this->facility = $INPUT->str('facility');
31        if (!in_array($this->facility, $this->facilities)) {
32            $this->facility = $this->facilities[0];
33        }
34
35        $this->date = $INPUT->str('date');
36        if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $this->date)) {
37            $this->date = gmdate('Y-m-d');
38        }
39    }
40
41    /** @inheritDoc */
42    public function html()
43    {
44        echo '<div id="plugin__logviewer">';
45        echo $this->locale_xhtml('intro');
46        $this->displayTabs();
47        $this->displayLog();
48        echo '</div>';
49    }
50
51    /**
52     * Show the navigational tabs and date picker
53     */
54    protected function displayTabs()
55    {
56        global $ID;
57
58        $form = new dokuwiki\Form\Form(['method' => 'GET']);
59        $form->setHiddenField('do', 'admin');
60        $form->setHiddenField('page', 'logviewer');
61        $form->setHiddenField('facility', $this->facility);
62        $form->addTextInput('date', $this->getLang('date'))
63            ->attr('type', 'date')->val($this->date)->addClass('quickselect');
64        $form->addButton('submit', '>')->attr('type', 'submit');
65        echo $form->toHTML();
66
67        echo '<ul class="tabs">';
68        foreach ($this->facilities as $facility) {
69            echo '<li>';
70            if ($facility == $this->facility) {
71                echo '<strong>' . hsc($facility) . '</strong>';
72            } else {
73                $link = wl($ID,
74                    ['do' => 'admin', 'page' => 'logviewer', 'date' => $this->date, 'facility' => $facility]);
75                echo '<a href="' . $link . '">' . hsc($facility) . '</a>';
76            }
77            echo '</li>';
78        }
79        echo '</ul>';
80
81    }
82
83    /**
84     * Output the logfile contents
85     */
86    protected function displayLog()
87    {
88        $logfile = Logger::getInstance($this->facility)->getLogfile($this->date);
89        if (!file_exists($logfile)) {
90            echo $this->locale_xhtml('nolog');
91            return;
92        }
93
94        // loop through the file an print it
95        echo '<dl>';
96        $lines = file($logfile);
97        $cnt = count($lines);
98        for ($i = 0; $i < $cnt; $i++) {
99            $line = $lines[$i];
100
101            if ($line[0] === ' ' && $line[1] === ' ') {
102                // lines indented by two spaces are details, aggregate them
103                echo '<dd>';
104                while (isset($line[0]) && $line[0] === ' ' && isset($line[1]) && $line[1] === ' ') {
105                    echo hsc(substr($line, 2)) . '<br />';
106                    $i++;
107                    $line = $lines[$i] ?? '';
108                }
109                echo '</dd>';
110                $i -= 1; // rewind the counter
111            } else {
112                // other lines are actual log lines in three parts
113                list($dt, $file, $msg) = sexplode("\t", $line, 3, '');
114                echo '<dt>';
115                echo '<span class="datetime">' . hsc($dt) . '</span>';
116                echo '<span class="log">';
117                echo '<span class="msg">' . hsc($msg) . '</span>';
118                echo '<span class="file">' . hsc($file) . '</span>';
119                echo '</span>';
120                echo '</dt>';
121            }
122        }
123        echo '</dl>';
124    }
125
126    /**
127     * Get the available logging facilities
128     *
129     * @return array
130     */
131    protected function getFacilities()
132    {
133        global $conf;
134        $conf['logdir'];
135
136        // default facilities first
137        $facilities = [
138            Logger::LOG_ERROR,
139            Logger::LOG_DEPRECATED,
140            Logger::LOG_DEBUG,
141        ];
142
143        // add all other dirs
144        $dirs = glob($conf['logdir'] . '/*', GLOB_ONLYDIR);
145        foreach ($dirs as $dir) {
146            $facilities[] = basename($dir);
147        }
148        $facilities = array_unique($facilities);
149
150        return $facilities;
151    }
152
153}
154
155