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