1<?php
2
3use dokuwiki\Extension\Event;
4use dokuwiki\Extension\SyntaxPlugin;
5
6/**
7 * DokuWiki Plugin notification (Syntax Component)
8 *
9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
10 * @author  Szymon Olewniczak <it@rid.pl>
11 */
12
13class syntax_plugin_notification_list extends SyntaxPlugin
14{
15    public function getType()
16    {
17        return 'substition';
18    }
19
20    public function getSort()
21    {
22        return 20;
23    }
24
25    public function PType()
26    {
27        return 'block';
28    }
29
30    public function connectTo($mode)
31    {
32        $this->Lexer->addSpecialPattern('----+ *notification list *-+\n.*?----+', $mode, 'plugin_notification_list');
33    }
34
35    public function handle($match, $state, $pos, Doku_Handler $handler)
36    {
37        $lines = explode("\n", $match);
38        array_shift($lines);
39        array_pop($lines);
40
41        $params = [
42            'plugin' => '.*',
43            'user' => '$USER$',
44            'full' => true,
45            'date' => '%Y-%m-%d'
46        ];
47        foreach ($lines as $line) {
48            $pair = explode(':', $line, 2);
49            if (count($pair) < 2) {
50                continue;
51            }
52            $key = trim($pair[0]);
53            $value = trim($pair[1]);
54
55            if ($key == 'full') {
56                $value = $value != '0';
57            }
58
59            $params[$key] = $value;
60        }
61        return $params;
62    }
63
64    /**
65     * Render xhtml output or metadata
66     *
67     * @param string        $mode     Renderer mode (supported modes: xhtml)
68     * @param Doku_Renderer $renderer The renderer
69     * @param array         $data     The data from the handler() function
70     *
71     * @return bool If rendering was successful.
72     */
73
74    public function render($mode, Doku_Renderer $renderer, $data)
75    {
76        if (!$data) {
77            return false;
78        }
79
80        $method = 'render' . ucfirst($mode);
81        if (method_exists($this, $method)) {
82            call_user_func([$this, $method], $renderer, $data);
83            return true;
84        }
85        return false;
86    }
87
88    /**
89     * @param $pattern
90     * @return array
91     */
92    protected function getNotificationPlugins($pattern)
93    {
94        $plugins = [];
95        Event::createAndTrigger('PLUGIN_NOTIFICATION_REGISTER_SOURCE', $plugins);
96        $plugins = preg_grep('/' . $pattern . '/', $plugins);
97
98        return $plugins;
99    }
100
101    /**
102     * Render metadata
103     *
104     * @param Doku_Renderer $renderer The renderer
105     * @param array         $data     The data from the handler() function
106     */
107    public function renderMetadata(Doku_Renderer $renderer, $data)
108    {
109        $plugin_name = $this->getPluginName();
110        if (!isset($renderer->meta['plugin'][$plugin_name])) {
111            $renderer->meta['plugin'][$plugin_name] = ['plugins' => []];
112        }
113        $plugins = $this->getNotificationPlugins($data['plugin']);
114        $old_plugins = $renderer->meta['plugin'][$plugin_name]['plugins'];
115
116        $renderer->meta['plugin'][$plugin_name]['plugins'] = array_unique(array_merge($plugins, $old_plugins));
117        if ($data['user'] == '$USER$') {
118            $renderer->meta['plugin'][$plugin_name]['dynamic user'] = true;
119        }
120    }
121
122    /**
123     * Render xhtml
124     *
125     * @param Doku_Renderer $renderer The renderer
126     * @param array         $data     The data from the handler() function
127     */
128    public function renderXhtml(Doku_Renderer $renderer, $data)
129    {
130        global $INFO;
131
132        $plugins = $this->getNotificationPlugins($data['plugin']);
133
134        if ($data['user'] == '$USER$') {
135            $data['user'] = $INFO['client'];
136        }
137
138        $notifications_data = [
139            'plugins' => $plugins,
140            'user' => $data['user'],
141            'notifications' => []
142        ];
143        Event::createAndTrigger('PLUGIN_NOTIFICATION_GATHER', $notifications_data);
144
145        $notifications = $notifications_data['notifications'];
146
147        if (!$notifications) {
148            $renderer->doc .= $this->getLang('no notifications');
149            return;
150        }
151
152        $renderer->doc .= '<ul>';
153
154        usort($notifications, function ($a, $b) {
155            if ($a['timestamp'] == $b['timestamp']) {
156                return 0;
157            }
158            return ($a['timestamp'] > $b['timestamp']) ? -1 : 1;
159        });
160
161        foreach ($notifications as $notification) {
162            $content = $notification[$data['full'] ? 'full' : 'brief'];
163            $timestamp = $notification['timestamp'];
164
165            $date = '';
166            if ($data['date']) {
167                $date = strftime($data['date'], $timestamp);
168            }
169
170            $renderer->doc .= "<li class=\"level1\"><div class=\"li\">$date $content</div></li>";
171        }
172        $renderer->doc .= '</ul>';
173    }
174}
175