1<?php
2
3use dokuwiki\Extension\SyntaxPlugin;
4use dokuwiki\File\PageResolver;
5
6/**
7 * DokuWiki Plugin tagging (Syntax Component)
8 *
9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
10 * @author  Adrian Lang <lang@cosmocode.de>
11 */
12class syntax_plugin_tagging extends SyntaxPlugin
13{
14    public function getType()
15    {
16        return 'substition';
17    }
18
19    public function getPType()
20    {
21        return 'block';
22    }
23
24    public function getSort()
25    {
26        return 13;
27    }
28
29    public function connectTo($mode)
30    {
31        $this->Lexer->addSpecialPattern('{{tagging::\w+(?:>[^}\?]+)?(?:\?\d+)?}}', $mode, 'plugin_tagging');
32    }
33
34    public function handle($match, $state, $pos, Doku_Handler $handler)
35    {
36        $data = [];
37        $matches = [];
38        preg_match('/{{tagging::(\w+)(?:>([^}\?]+))?(\?\d+)?}}/', $match, $matches);
39        $data['cmd'] = $matches[1];
40        $data['limit'] = (int)ltrim($matches[3] ?? '', '?');
41        if (!$data['limit']) {
42            $data['limit'] = $this->getConf('cloudlimit');
43        }
44
45        switch ($data['cmd']) {
46            case 'user':
47                if (count($matches) > 2) {
48                    $data['user'] = trim($matches[2]);
49                }
50                break;
51            case 'tag':
52                if (count($matches) > 2) {
53                    $data['tag'] = trim($matches[2]);
54                }
55                break;
56            case 'ns':
57                if (count($matches) > 2) {
58                    $data['ns'] = trim($matches[2]);
59                }
60                break;
61            case 'manage':
62                if (count($matches) > 2) {
63                    $data['manage'] = trim($matches[2]);
64                }
65                break;
66        }
67
68        return $data;
69    }
70
71    public function render($mode, Doku_Renderer $renderer, $data)
72    {
73        if ($mode !== 'xhtml') {
74            return false;
75        }
76
77        /** @var helper_plugin_tagging $hlp */
78        $hlp = plugin_load('helper', 'tagging');
79
80        switch ($data['cmd']) {
81            case 'user':
82                $renderer->info['cache'] = false;
83                if (!isset($data['user'])) {
84                    $data['user'] = $_SERVER['REMOTE_USER'];
85                }
86                $tags = $hlp->findItems(['tagger' => $data['user']], 'tag', $data['limit']);
87
88                $renderer->doc .= $hlp->html_cloud($tags, 'tag', [$hlp, 'linkToSearch'], true, true);
89
90                break;
91            case 'tag':
92                $renderer->info['cache'] = false;
93
94                $pids = $hlp->findItems(['tag' => $data['tag']], 'pid', $data['limit']);
95
96                $renderer->doc .= $hlp->html_page_list($pids);
97
98                break;
99            case 'ns':
100                $renderer->info['cache'] = false;
101                if (!isset($data['ns'])) {
102                    global $INFO;
103                    $data['ns'] = $INFO['namespace'];
104                }
105                global $ID;
106                $resolver = new PageResolver($ID);
107                $data['ns'] = $resolver->resolveId($data['ns'] . ':');
108                if ($data['ns'] !== '') {
109                    // Do not match nsbla, only ns:bla
110                    $data['ns'] .= ':';
111                }
112                $tags = $hlp->findItems(['pid' => $hlp->globNamespace($data['ns'])], 'tag', $data['limit']);
113                $renderer->doc .= $hlp->html_cloud($tags, 'tag', [$hlp, 'linkToSearch'], true, true, $data['ns']);
114
115                break;
116            case 'input':
117                $renderer->nocache();
118                $renderer->doc .= $hlp->tpl_tags(false);
119                break;
120            case 'manage':
121                $renderer->nocache();
122                $ns = $data['manage'] ?: '';
123                $renderer->doc .= $hlp->manageTags($ns);
124                break;
125        }
126
127        return true;
128    }
129}
130