xref: /plugin/ireadit/syntax/list.php (revision dfc7cf2977051d04499fe61d5eaf52bafa3d8038)
1<?php
2
3// must be run within DokuWiki
4if(!defined('DOKU_INC')) die();
5
6
7class syntax_plugin_ireadit_list extends DokuWiki_Syntax_Plugin {
8
9    function getType() {
10        return 'substition';
11    }
12
13    function getSort() {
14        return 20;
15    }
16
17    function PType() {
18        return 'block';
19    }
20
21    function connectTo($mode) {
22        $this->Lexer->addSpecialPattern('----+ *ireadit list *-+\n.*?----+', $mode,'plugin_ireadit_list');
23    }
24
25    function handle($match, $state, $pos, Doku_Handler $handler){
26        $lines = explode("\n", $match);
27        array_shift($lines);
28        array_pop($lines);
29
30        $statemap = [
31            'read' => ['read'],
32            'outdated' => ['outdated'],
33            'unread' => ['unread'],
34            'not read' => ['outdated', 'unread'],
35            'all' => ['read', 'outdated', 'unread'],
36        ];
37
38        $params = [
39            'user' => '$USER$',
40            'state' => $statemap['all'],
41            'lastread' => '0',
42            'overview' => '0',
43            'namespace' => '',
44            'filter' => false
45        ];
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            if ($key == 'state') {
55                $states = array_map('trim', explode(',', strtolower($value)));
56                $value = [];
57                foreach ($states as $state) {
58                    if (isset($statemap[$state])) {
59                        $value = array_merge($value, $statemap[$state]);
60                    } else {
61                        msg('ireadit plugin: unknown state "'.$state.'" should be: ' .
62                            implode(', ', array_keys($statemap)), -1);
63                        return false;
64                    }
65                }
66            } elseif ($key == 'namespace') {
67                $value = trim(cleanID($value), ':');
68            } elseif($key == 'filter') {
69                $value = trim($value, '/');
70                if (preg_match('/' . $value . '/', null) === false) {
71                    msg('ireadit plugin: invalid filter regex', -1);
72                    return false;
73                }
74            } elseif ($key == 'lastread') {
75                if ($value != '0' && $value != '1') {
76                    msg('ireadit plugin: lastread should be 0 or 1', -1);
77                    return false;
78                }
79            } elseif ($key == 'overview') {
80                if ($value != '0' && $value != '1') {
81                    msg('ireadit plugin: overview should be 0 or 1', -1);
82                    return false;
83                }
84            }
85            $params[$key] = $value;
86        }
87        return $params;
88    }
89
90    /**
91     * Render xhtml output or metadata
92     *
93     * @param string        $mode     Renderer mode (supported modes: xhtml)
94     * @param Doku_Renderer $renderer The renderer
95     * @param array         $data     The data from the handler() function
96     *
97     * @return bool If rendering was successful.
98     */
99
100    public function render($mode, Doku_Renderer $renderer, $data)
101    {
102        $method = 'render' . ucfirst($mode);
103        if (method_exists($this, $method)) {
104            call_user_func([$this, $method], $renderer, $data);
105            return true;
106        }
107        return false;
108    }
109
110    /**
111     * Render metadata
112     *
113     * @param Doku_Renderer $renderer The renderer
114     * @param array         $params     The data from the handler() function
115     */
116    public function renderMetadata(Doku_Renderer $renderer, $params)
117    {
118        $renderer->meta['plugin']['ireadit_list'] = [];
119
120        if ($params['user'] == '$USER$') {
121            $renderer->meta['plugin']['ireadit_list']['dynamic_user'] = true;
122        }
123    }
124
125    public function renderXhtml(Doku_Renderer $renderer, $params)
126    {
127        global $INFO;
128
129        try {
130            /** @var \helper_plugin_ireadit_db $db_helper */
131            $db_helper = plugin_load('helper', 'ireadit_db');
132            $sqlite = $db_helper->getDB();
133        } catch (Exception $e) {
134            msg($e->getMessage(), -1);
135            return false;
136        }
137
138        if ($params['user'] == '$USER$') {
139            $params['user'] = $INFO['client'];
140        }
141
142        $query_args = [$params['namespace'].'%'];
143	$filter_q = '';
144
145        if ($params['filter']) {
146            $query_args[] = $params['filter'];
147            $filter_q .= " AND I.page REGEXP ?";
148        }
149
150        if ($params['overview'] == '1') {
151            $q = "SELECT I.page, I.timestamp,
152                    (SELECT T.rev FROM ireadit T
153                    WHERE T.page=I.page AND T.timestamp IS NOT NULL
154                    ORDER BY rev DESC LIMIT 1) lastread
155                    FROM ireadit I INNER JOIN meta M ON I.page = M.page AND I.rev = M.last_change_date
156                    WHERE I.page LIKE ? ESCAPE '_'
157                    $filter_q";
158            $res = $sqlite->query($q, $query_args);
159        } else {
160            array_unshift($query_args, $params['user'], $params['user']);
161            $q = "SELECT I.page, I.timestamp,
162                    (SELECT T.rev FROM ireadit T
163                    WHERE T.page=I.page AND T.user=? AND T.timestamp IS NOT NULL
164                    ORDER BY rev DESC LIMIT 1) lastread
165                    FROM ireadit I INNER JOIN meta M ON I.page = M.page AND I.rev = M.last_change_date
166                    WHERE I.user=?
167                    AND I.page LIKE ? ESCAPE '_'
168                    $filter_q";
169            $res = $sqlite->query($q, $query_args);
170        }
171
172        // Output List
173        $renderer->doc .= '<ul>';
174        while ($row = $sqlite->res_fetch_assoc($res)) {
175            $page = $row['page'];
176            $timestamp = $row['timestamp'];
177            $lastread = $row['lastread'];
178
179            if (!$timestamp && $lastread) {
180                $state = 'outdated';
181            } elseif (!$timestamp && !$lastread) {
182                $state = 'unread';
183            } else {
184                $state = 'read';
185            }
186
187            if (!in_array($state, $params['state'])) {
188                continue;
189            }
190
191            $urlParameters = [];
192            if ($params['lastread'] && $state == 'outdated') {
193                $urlParameters['rev'] = $lastread;
194            }
195            $url = wl($page, $urlParameters);
196            $link = '<a class="wikilink1" href="' . $url . '">';
197            if (useHeading('content')) {
198                $heading = p_get_first_heading($page);
199                if (!blank($heading)) {
200                    $link .= $heading;
201                } else {
202                    $link .= noNSorNS($page);
203                }
204            } else {
205                $link .= noNSorNS($page);
206            }
207            $link .= '</a>';
208            $renderer->doc .= '<li class="li">' . $link . '</li>';
209        }
210        $renderer->doc .= '</ul>';
211    }
212}
213