1<?php
2
3/**
4 * Pagelist Plugin: lists pages
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Esther Brunner <wikidesign@gmail.com>
8 */
9
10class syntax_plugin_pagelist extends DokuWiki_Syntax_Plugin
11{
12
13    public function getType()
14    {
15        return 'substition';
16    }
17
18    public function getPType()
19    {
20        return 'block';
21    }
22
23    public function getSort()
24    {
25        return 168;
26    }
27
28    /**
29     * Connect pattern to lexer
30     *
31     * @param string $mode
32     */
33    public function connectTo($mode)
34    {
35        $this->Lexer->addSpecialPattern('<pagelist.+?</pagelist>', $mode, 'plugin_pagelist');
36    }
37
38    /**
39     * Handle the match
40     *
41     * @param string $match The text matched by the patterns
42     * @param int $state The lexer state for the match
43     * @param int $pos The character position of the matched text
44     * @param Doku_Handler $handler The Doku_Handler object
45     * @return  array Return an array with all data you want to use in render
46     */
47    public function handle($match, $state, $pos, Doku_Handler $handler)
48    {
49        global $ID;
50
51        $match = substr($match, 9, -11);  // strip markup
52        list($flags, $match) = array_pad(explode('>', $match, 2), 2, null);
53        $flags = explode('&', substr($flags, 1));
54        $items = explode('*', $match);
55
56        $pages = [];
57        $count = count($items);
58        for ($i = 0; $i < $count; $i++) {
59            if (!preg_match('/\[\[(.+?)]]/', $items[$i], $match)) continue;
60            list($id, $title, $description) = array_pad(explode('|', $match[1], 3), 3, null);
61            list($id, $section) = array_pad(explode('#', $id, 2), 2, null);
62            if (!$id) $id = $ID;
63
64            // Igor and later
65            if (class_exists('dokuwiki\File\PageResolver')) {
66                $resolver = new dokuwiki\File\PageResolver($ID);
67                $id = $resolver->resolveId($id);
68                $exists = page_exists($id);
69            } else {
70                // Compatibility with older releases
71                resolve_pageid(getNS($ID), $id, $exists);
72            }
73
74            // page has an image title
75            if (($title) && (preg_match('/\{\{(.+?)}}/', $title, $match))) {
76                list($image, $title) = array_pad(explode('|', $match[1], 2), 2, null);
77                list(, $mime) = mimetype($image);
78                if (!substr($mime, 0, 5) == 'image') $image = '';
79                $pages[] = [
80                    'id' => $id,
81                    'section' => cleanID($section),
82                    'title' => trim($title),
83                    'titleimage' => trim($image),
84                    'description' => trim($description), // Holds the added parameter for own descriptions
85                ];
86
87
88            } else {
89                // text title (if any)
90                $pages[] = [
91                    'id' => $id,
92                    'section' => cleanID($section),
93                    'title' => trim($title),
94                    'description' => trim($description), // Holds the added parameter for own descriptions
95                ];
96            }
97        }
98        return [$flags, $pages];
99    }
100
101    /**
102     * Create output
103     *
104     * @param string $format output format being rendered
105     * @param Doku_Renderer $renderer the current renderer object
106     * @param array $data data created by handler()
107     * @return boolean rendered correctly?
108     */
109    public function render($format, Doku_Renderer $renderer, $data)
110    {
111        list($flags, $pages) = $data;
112
113        foreach ($pages as $i => $page) {
114            $pages[$i]['exists'] = page_exists($page['id']);
115        }
116
117        // for XHTML output
118        if ($format == 'xhtml') {
119            /** @var helper_plugin_pagelist $pagelist */
120            if (!$pagelist = plugin_load('helper', 'pagelist')) return false;
121            $pagelist->setFlags($flags);
122            $pagelist->startList();
123
124            foreach ($pages as $page) {
125                $pagelist->addPage($page);
126            }
127            $renderer->doc .= $pagelist->finishList();
128            return true;
129
130            // for metadata renderer
131        } elseif ($format == 'metadata') {
132            /** @var Doku_Renderer_metadata $renderer */
133            foreach ($pages as $page) {
134                $renderer->meta['relation']['references'][$page['id']] = $page['exists'];
135            }
136            return true;
137        }
138        return false;
139    }
140}
141