xref: /plugin/struct/action/output.php (revision 8b04ed8174b19d68efb6bd7e781d1086fe9750ca)
1<?php
2/**
3 * DokuWiki Plugin struct (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
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    const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT';
24
25    /**
26     * Registers a callback function for a given event
27     *
28     * @param Doku_Event_Handler $controller DokuWiki's event controller object
29     * @return void
30     */
31    public function register(Doku_Event_Handler $controller) {
32        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handle_output');
33        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replace_dw2pdf');
34        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanup_dw2pdf');
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 handle_output(Doku_Event $event, $param) {
45        global $ID;
46        if(!page_exists($ID)) return;
47        $ins = -1;
48        $pos = 0;
49        foreach($event->data->calls as $num => $call) {
50            // try to find the first header
51            if($call[0] == 'header') {
52                $pos = $call[2];
53                $ins = $num;
54                break;
55            }
56
57            // abort when after we looked at the first 150 bytes
58            if(isset($call[3]) && $call[3] > 150) {
59                break;
60            }
61        }
62
63        // insert our own call after the found position
64        array_splice(
65            $event->data->calls,
66            $ins+1,
67            0,
68            array(
69                array(
70                    'plugin',
71                    array(
72                        'struct_output', array('pos' => $pos), DOKU_LEXER_SPECIAL, ''
73                    ),
74                    $pos
75                )
76            )
77        );
78    }
79
80    /**
81     * If the page has a schema assigned, add its struct data
82     * to dw2pdf's template replacements
83     *
84     * @param Doku_Event $event
85     * @param $param
86     */
87    public function replace_dw2pdf(Doku_Event $event, $param)
88    {
89        if (!$event->data['id'] || !page_exists($event->data['id'])) return;
90
91        global $REV;
92        $rev = $REV ?: time();
93
94        /** @var helper_plugin_struct $helper */
95        $helper = plugin_load('helper', 'struct');
96        $data = $helper->getData($event->data['id'], null, $rev);
97
98        if(!$data) return;
99
100        foreach ($data as $schema => $fields) {
101            foreach ($fields as $field => $value) {
102                $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field);
103                $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value;
104            }
105        }
106    }
107
108    /**
109     * Remove struct placeholders still present after replacement.
110     * Requested data was not found.
111     *
112     * @param Doku_Event $event
113     * @param $param
114     */
115    public function cleanup_dw2pdf(Doku_Event $event, $param)
116    {
117        $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~';
118        $event->data['content'] = preg_replace($pattern, '', $event->data['content']);
119    }
120
121}
122
123// vim:ts=4:sw=4:et:
124