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_$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 render_metadata(Doku_Renderer $renderer, $params)
117    {
118        $renderer->meta['plugin_ireadit_list'] = true;
119    }
120
121    public function render_xhtml(Doku_Renderer $renderer, $params)
122    {
123        global $INFO;
124
125        try {
126            /** @var \helper_plugin_ireadit_db $db_helper */
127            $db_helper = plugin_load('helper', 'ireadit_db');
128            $sqlite = $db_helper->getDB();
129        } catch (Exception $e) {
130            msg($e->getMessage(), -1);
131            return false;
132        }
133
134        //overview overrides user setting
135        if ($params['overview'] == '1') {
136            $user = NULL;
137        } elseif ($params['user'] == '$USER$') {
138            $user = $INFO['client'];
139        } else {
140            $user = $params['user'];
141        }
142
143        /** @var helper_plugin_ireadit $helper */
144        $helper = $this->loadHelper('ireadit');
145        $pages = $helper->get_list($user);
146
147        // apply "filter" and "namespace"
148        $pages = array_filter($pages, function ($k) use ($params) {
149            return substr($k, 0, strlen($params['namespace'])) == $params['namespace'];
150        }, ARRAY_FILTER_USE_KEY);
151        $pages = array_filter($pages, function ($k) use ($params) {
152            return preg_match('/' . $params['filter'] . '/', $k);
153        }, ARRAY_FILTER_USE_KEY);
154
155        // Output List
156        $renderer->doc .= '<ul>';
157        foreach ($pages as $page => $row) {
158            if (!in_array($row['state'], $params['state'])) {
159                continue;
160            }
161
162            $urlParameters = [];
163            if ($params['lastread'] && $row['state'] == 'outdated') {
164                $urlParameters['rev'] = $row['last_read_rev'];
165            // in case of approve integration current_rev may be last approved revision
166            } elseif ($this->getConf('approve_integration') &&
167                $row['current_rev'] != p_get_metadata($page, 'last_change date')) {
168                $urlParameters['rev'] = $row['current_rev'];
169            }
170            $url = wl($page, $urlParameters);
171            $link = '<a class="wikilink1" href="' . $url . '">';
172            if (useHeading('content')) {
173                $heading = p_get_first_heading($page);
174                if (!blank($heading)) {
175                    $link .= $heading;
176                } else {
177                    $link .= noNSorNS($page);
178                }
179            } else {
180                $link .= noNSorNS($page);
181            }
182            $link .= '</a>';
183            $renderer->doc .= '<li class="li">' . $link . '</li>';
184        }
185        $renderer->doc .= '</ul>';
186
187        return true;
188    }
189}
190