xref: /plugin/struct/action/output.php (revision e6a2e26b57dd1411a582eba0bdba877d874c7fa3)
1<?php
2
3/**
4 * DokuWiki Plugin struct (Action Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8 */
9
10/**
11 * Class action_plugin_struct_output
12 *
13 * This action component handles the automatic output of all schema data that has been assigned
14 * to the current page by appending the appropriate instruction to the handler calls.
15 *
16 * The real output creation is done within the syntax component
17 * @see syntax_plugin_struct_output
18 */
19class action_plugin_struct_output extends DokuWiki_Action_Plugin
20{
21
22    const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT';
23
24    /**
25     * Registers a callback function for a given event
26     *
27     * @param Doku_Event_Handler $controller DokuWiki's event controller object
28     * @return void
29     */
30    public function register(Doku_Event_Handler $controller)
31    {
32        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handleOutput');
33        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replaceDw2pdf');
34        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanupDw2pdf');
35    }
36
37    /**
38     * Appends the instruction to render our syntax output component to each page
39     * after the first found headline or the very begining if no headline was found
40     *
41     * @param Doku_Event $event
42     * @param $param
43     */
44    public function handleOutput(Doku_Event $event, $param)
45    {
46        global $ID;
47        if (!page_exists($ID)) return;
48
49        // display struct data at the bottom?
50        if ($this->getConf('bottomoutput')) {
51            $event->data->calls[] = [
52                'plugin',
53                ['struct_output', [], DOKU_LEXER_SPECIAL, ''],
54                null
55            ];
56        } else {
57            $ins = -1;
58            $pos = 0;
59            foreach ($event->data->calls as $num => $call) {
60                // try to find the first header
61                if ($call[0] == 'header') {
62                    $pos = $call[2];
63                    $ins = $num;
64                    break;
65                }
66
67                // abort when after we looked at the first 150 bytes
68                if (isset($call[3]) && $call[3] > 150) {
69                    break;
70                }
71            }
72
73            // insert our own call after the found position
74            array_splice(
75                $event->data->calls,
76                $ins + 1,
77                0,
78                array(
79                    array(
80                        'plugin',
81                        array(
82                            'struct_output', array('pos' => $pos), DOKU_LEXER_SPECIAL, ''
83                        ),
84                        $pos
85                    )
86                )
87            );
88        }
89    }
90
91    /**
92     * If the page has a schema assigned, add its struct data
93     * to dw2pdf's template replacements
94     *
95     * @param Doku_Event $event
96     * @param $param
97     */
98    public function replaceDw2pdf(Doku_Event $event, $param)
99    {
100        if (!$event->data['id'] || !page_exists($event->data['id'])) return;
101
102        global $REV;
103        $rev = $REV ?: time();
104
105        /** @var helper_plugin_struct $helper */
106        $helper = plugin_load('helper', 'struct');
107        $data = $helper->getData($event->data['id'], null, $rev);
108
109        if (!$data) return;
110
111        foreach ($data as $schema => $fields) {
112            foreach ($fields as $field => $value) {
113                $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field);
114                $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value;
115            }
116        }
117    }
118
119    /**
120     * Remove struct placeholders still present after replacement.
121     * Requested data was not found.
122     *
123     * @param Doku_Event $event
124     * @param $param
125     */
126    public function cleanupDw2pdf(Doku_Event $event, $param)
127    {
128        $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~';
129        $event->data['content'] = preg_replace($pattern, '', $event->data['content']);
130    }
131}
132
133// vim:ts=4:sw=4:et:
134