xref: /plugin/struct/action/output.php (revision d6d97f6064c3b0f90310be8341edc9585520ee54)
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// must be run within Dokuwiki
11if (!defined('DOKU_INC')) die();
12
13/**
14 * Class action_plugin_struct_output
15 *
16 * This action component handles the automatic output of all schema data that has been assigned
17 * to the current page by appending the appropriate instruction to the handler calls.
18 *
19 * The real output creation is done within the syntax component
20 * @see syntax_plugin_struct_output
21 */
22class action_plugin_struct_output extends DokuWiki_Action_Plugin
23{
24
25    const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT';
26
27    /**
28     * Registers a callback function for a given event
29     *
30     * @param Doku_Event_Handler $controller DokuWiki's event controller object
31     * @return void
32     */
33    public function register(Doku_Event_Handler $controller)
34    {
35        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handle_output');
36        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replace_dw2pdf');
37        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanup_dw2pdf');
38    }
39
40    /**
41     * Appends the instruction to render our syntax output component to each page
42     * after the first found headline or the very begining if no headline was found
43     *
44     * @param Doku_Event $event
45     * @param $param
46     */
47    public function handle_output(Doku_Event $event, $param)
48    {
49        global $ID;
50        if (!page_exists($ID)) return;
51        $ins = -1;
52        $pos = 0;
53        foreach ($event->data->calls as $num => $call) {
54            // try to find the first header
55            if ($call[0] == 'header') {
56                $pos = $call[2];
57                $ins = $num;
58                break;
59            }
60
61            // abort when after we looked at the first 150 bytes
62            if (isset($call[3]) && $call[3] > 150) {
63                break;
64            }
65        }
66
67        // insert our own call after the found position
68        array_splice(
69            $event->data->calls,
70            $ins + 1,
71            0,
72            array(
73                array(
74                    'plugin',
75                    array(
76                        'struct_output', array('pos' => $pos), DOKU_LEXER_SPECIAL, ''
77                    ),
78                    $pos
79                )
80            )
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 replace_dw2pdf(Doku_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            foreach ($fields as $field => $value) {
106                $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field);
107                $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value;
108            }
109        }
110    }
111
112    /**
113     * Remove struct placeholders still present after replacement.
114     * Requested data was not found.
115     *
116     * @param Doku_Event $event
117     * @param $param
118     */
119    public function cleanup_dw2pdf(Doku_Event $event, $param)
120    {
121        $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~';
122        $event->data['content'] = preg_replace($pattern, '', $event->data['content']);
123    }
124}
125
126// vim:ts=4:sw=4:et:
127