1<?php
2
3use dokuwiki\Utf8\PhpString;
4use dokuwiki\Utf8\Sort;
5
6/**
7 * DokuWiki Plugin autoindex (Syntax Component)
8 *
9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
10 * @author  Andreas Gohr <gohr@cosmocode.de>
11 */
12class syntax_plugin_autoindex extends \dokuwiki\Extension\SyntaxPlugin
13{
14    /** @inheritDoc */
15    public function getType()
16    {
17        return 'substition';
18    }
19
20    /** @inheritDoc */
21    public function getSort()
22    {
23        return 155;
24    }
25
26    /** @inheritDoc */
27    public function getPType()
28    {
29        return 'block';
30    }
31
32    /** @inheritDoc */
33    public function connectTo($mode)
34    {
35        $this->Lexer->addSpecialPattern('{{autoindex}}', $mode, 'plugin_autoindex');
36    }
37
38    /** @inheritDoc */
39    public function handle($match, $state, $pos, Doku_Handler $handler)
40    {
41        $data = array();
42
43        return $data;
44    }
45
46    /** @inheritDoc */
47    public function render($format, Doku_Renderer $renderer, $data)
48    {
49        global $INFO;
50        global $conf;
51
52        if ($format === 'metadata') {
53            return false;
54        }
55
56        $opts = [
57            'listfiles' => true,
58            'pagesonly' => true,
59            'firsthead' => true,
60            'depth' => 1,
61        ];
62        $data = [];
63        $ns = ':' . cleanID(getNS($INFO['id']));
64        $ns = utf8_encodeFN(str_replace(':', '/', $ns));
65
66        search($data, $conf['datadir'], 'search_universal', $opts, $ns, 1, '');
67        uasort($data, [$this, 'titleSort']);
68
69        if ($format === 'xhtml') {
70            $renderer->doc .= '<div class="plugin_autoindex">';
71        }
72
73        $last = '';
74        foreach ($data as $page) {
75            $first = PhpString::strtoupper(PhpString::substr($page['title'], 0, 1));
76            if ($first !== $last) {
77                if ($last !== '') {
78                    $renderer->listu_close();
79                    if ($format === 'xhtml') $renderer->doc .= '</div>';
80                }
81
82                $last = $first;
83                if ($format === 'xhtml') $renderer->doc .= '<div>';
84                $renderer->header($first, 2, 0);
85                $renderer->listu_open();
86            }
87
88            $renderer->listitem_open(1);
89            $renderer->listcontent_open();
90            $renderer->internallink($page['id'], $page['title']);
91            $renderer->listcontent_close();
92            $renderer->listitem_close();
93        }
94
95        if ($last !== '') {
96            $renderer->listu_close();
97            if ($format === 'xhtml') $renderer->doc .= '<div>';
98        }
99
100        if ($format === 'xhtml') {
101            $renderer->doc .= '</div>';
102        }
103
104        return true;
105    }
106
107    /**
108     * Custom comparator for sorting by title
109     *
110     * @param array $a
111     * @param array $b
112     * @return int
113     */
114    public function titleSort($a, $b)
115    {
116        return Sort::strcmp($a['title'], $b['title']);
117    }
118}
119
120