xref: /plugin/struct/action/output.php (revision 23f770ed1bbb18bafd6c16b9b0ad5492215b97db)
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
10use dokuwiki\plugin\struct\meta\Schema;
11
12/**
13 * Class action_plugin_struct_output
14 *
15 * This action component handles the automatic output of all schema data that has been assigned
16 * to the current page by appending the appropriate instruction to the handler calls.
17 *
18 * The real output creation is done within the syntax component
19 * @see syntax_plugin_struct_output
20 */
21class action_plugin_struct_output extends DokuWiki_Action_Plugin
22{
23
24    const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT';
25
26    /**
27     * Registers a callback function for a given event
28     *
29     * @param Doku_Event_Handler $controller DokuWiki's event controller object
30     * @return void
31     */
32    public function register(Doku_Event_Handler $controller)
33    {
34        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handleOutput');
35        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replaceDw2pdf');
36        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanupDw2pdf');
37    }
38
39    /**
40     * Appends the instruction to render our syntax output component to each page
41     * after the first found headline or the very begining if no headline was found
42     *
43     * @param Doku_Event $event
44     * @param $param
45     */
46    public function handleOutput(Doku_Event $event, $param)
47    {
48        global $ID;
49        if (!page_exists($ID)) return;
50
51        $pos = 0;
52        $ins = -1;
53
54        // display struct data at the bottom?
55        if ($this->getConf('bottomoutput')) {
56            $ins = count($event->data->calls);
57        } else if (!$this->getConf('topoutput')) {
58            foreach ($event->data->calls as $num => $call) {
59                // try to find the first header
60                if ($call[0] == 'header') {
61                    $pos = $call[2];
62                    $ins = $num;
63                    break;
64                }
65
66                // abort when after we looked at the first 150 bytes
67                if (isset($call[3]) && $call[3] > 150) {
68                    break;
69                }
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     * If the page has a schema assigned, add its struct data
92     * to dw2pdf's template replacements
93     *
94     * @param Doku_Event $event
95     * @param $param
96     */
97    public function replaceDw2pdf(Doku_Event $event, $param)
98    {
99        if (!$event->data['id'] || !page_exists($event->data['id'])) return;
100
101        global $REV;
102        $rev = $REV ?: time();
103
104        /** @var helper_plugin_struct $helper */
105        $helper = plugin_load('helper', 'struct');
106        $data = $helper->getData($event->data['id'], null, $rev);
107
108        if (!$data) return;
109
110        foreach ($data as $schema => $fields) {
111            $schemaObject = new Schema($schema);
112            foreach ($fields as $field => $value) {
113                // format fields
114                $col = $schemaObject->findColumn($field);
115                if (is_a($col->getType(), '\dokuwiki\plugin\struct\types\Date')) {
116                    $format = $col->getType()->getConfig()['format'];
117                    $value = date($format, strtotime($value));
118                }
119
120                $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field);
121                $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value;
122            }
123        }
124    }
125
126    /**
127     * Remove struct placeholders still present after replacement.
128     * Requested data was not found.
129     *
130     * @param Doku_Event $event
131     * @param $param
132     */
133    public function cleanupDw2pdf(Doku_Event $event, $param)
134    {
135        $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~';
136        $event->data['content'] = preg_replace($pattern, '', $event->data['content']);
137    }
138}
139
140// vim:ts=4:sw=4:et:
141