xref: /plugin/struct/action/output.php (revision e6a2e26b57dd1411a582eba0bdba877d874c7fa3)
182c064c1SAndreas Gohr<?php
2d6d97f60SAnna Dabrowska
382c064c1SAndreas Gohr/**
482c064c1SAndreas Gohr * DokuWiki Plugin struct (Action Component)
582c064c1SAndreas Gohr *
682c064c1SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
782c064c1SAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
882c064c1SAndreas Gohr */
982c064c1SAndreas Gohr
1082c064c1SAndreas Gohr/**
1182c064c1SAndreas Gohr * Class action_plugin_struct_output
1282c064c1SAndreas Gohr *
1382c064c1SAndreas Gohr * This action component handles the automatic output of all schema data that has been assigned
1482c064c1SAndreas Gohr * to the current page by appending the appropriate instruction to the handler calls.
1582c064c1SAndreas Gohr *
1682c064c1SAndreas Gohr * The real output creation is done within the syntax component
1782c064c1SAndreas Gohr * @see syntax_plugin_struct_output
1882c064c1SAndreas Gohr */
19d6d97f60SAnna Dabrowskaclass action_plugin_struct_output extends DokuWiki_Action_Plugin
20d6d97f60SAnna Dabrowska{
2182c064c1SAndreas Gohr
223851b2fbSAnna Dabrowska    const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT';
233851b2fbSAnna Dabrowska
2482c064c1SAndreas Gohr    /**
2582c064c1SAndreas Gohr     * Registers a callback function for a given event
2682c064c1SAndreas Gohr     *
2782c064c1SAndreas Gohr     * @param Doku_Event_Handler $controller DokuWiki's event controller object
2882c064c1SAndreas Gohr     * @return void
2982c064c1SAndreas Gohr     */
30d6d97f60SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
31d6d97f60SAnna Dabrowska    {
32748e747fSAnna Dabrowska        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handleOutput');
33748e747fSAnna Dabrowska        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replaceDw2pdf');
34748e747fSAnna Dabrowska        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanupDw2pdf');
3582c064c1SAndreas Gohr    }
3682c064c1SAndreas Gohr
3782c064c1SAndreas Gohr    /**
3882c064c1SAndreas Gohr     * Appends the instruction to render our syntax output component to each page
3928b818ceSAndreas Gohr     * after the first found headline or the very begining if no headline was found
4082c064c1SAndreas Gohr     *
4182c064c1SAndreas Gohr     * @param Doku_Event $event
4282c064c1SAndreas Gohr     * @param $param
4382c064c1SAndreas Gohr     */
44748e747fSAnna Dabrowska    public function handleOutput(Doku_Event $event, $param)
45d6d97f60SAnna Dabrowska    {
460e4a3e7cSMichael Große        global $ID;
4702481400SAndreas Gohr        if (!page_exists($ID)) return;
48*e6a2e26bSAnna Dabrowska
49*e6a2e26bSAnna Dabrowska        // display struct data at the bottom?
50*e6a2e26bSAnna Dabrowska        if ($this->getConf('bottomoutput')) {
51*e6a2e26bSAnna Dabrowska            $event->data->calls[] = [
52*e6a2e26bSAnna Dabrowska                'plugin',
53*e6a2e26bSAnna Dabrowska                ['struct_output', [], DOKU_LEXER_SPECIAL, ''],
54*e6a2e26bSAnna Dabrowska                null
55*e6a2e26bSAnna Dabrowska            ];
56*e6a2e26bSAnna Dabrowska        } else {
5728b818ceSAndreas Gohr            $ins = -1;
5828b818ceSAndreas Gohr            $pos = 0;
5928b818ceSAndreas Gohr            foreach ($event->data->calls as $num => $call) {
6028b818ceSAndreas Gohr                // try to find the first header
6128b818ceSAndreas Gohr                if ($call[0] == 'header') {
6228b818ceSAndreas Gohr                    $pos = $call[2];
6328b818ceSAndreas Gohr                    $ins = $num;
6428b818ceSAndreas Gohr                    break;
6528b818ceSAndreas Gohr                }
6682c064c1SAndreas Gohr
6728b818ceSAndreas Gohr                // abort when after we looked at the first 150 bytes
689007da58SMichael Große                if (isset($call[3]) && $call[3] > 150) {
6928b818ceSAndreas Gohr                    break;
7028b818ceSAndreas Gohr                }
7128b818ceSAndreas Gohr            }
7228b818ceSAndreas Gohr
7328b818ceSAndreas Gohr            // insert our own call after the found position
7428b818ceSAndreas Gohr            array_splice(
7528b818ceSAndreas Gohr                $event->data->calls,
7628b818ceSAndreas Gohr                $ins + 1,
7728b818ceSAndreas Gohr                0,
7828b818ceSAndreas Gohr                array(
7928b818ceSAndreas Gohr                    array(
8082c064c1SAndreas Gohr                        'plugin',
8182c064c1SAndreas Gohr                        array(
825a1eab78SAndreas Gohr                            'struct_output', array('pos' => $pos), DOKU_LEXER_SPECIAL, ''
8382c064c1SAndreas Gohr                        ),
8482c064c1SAndreas Gohr                        $pos
8528b818ceSAndreas Gohr                    )
8628b818ceSAndreas Gohr                )
8782c064c1SAndreas Gohr            );
8882c064c1SAndreas Gohr        }
89*e6a2e26bSAnna Dabrowska    }
9082c064c1SAndreas Gohr
913851b2fbSAnna Dabrowska    /**
923851b2fbSAnna Dabrowska     * If the page has a schema assigned, add its struct data
933851b2fbSAnna Dabrowska     * to dw2pdf's template replacements
943851b2fbSAnna Dabrowska     *
953851b2fbSAnna Dabrowska     * @param Doku_Event $event
963851b2fbSAnna Dabrowska     * @param $param
973851b2fbSAnna Dabrowska     */
98748e747fSAnna Dabrowska    public function replaceDw2pdf(Doku_Event $event, $param)
993851b2fbSAnna Dabrowska    {
1003851b2fbSAnna Dabrowska        if (!$event->data['id'] || !page_exists($event->data['id'])) return;
1013851b2fbSAnna Dabrowska
102d4897163SAnna Dabrowska        global $REV;
103d4897163SAnna Dabrowska        $rev = $REV ?: time();
104d4897163SAnna Dabrowska
1053851b2fbSAnna Dabrowska        /** @var helper_plugin_struct $helper */
1063851b2fbSAnna Dabrowska        $helper = plugin_load('helper', 'struct');
107d4897163SAnna Dabrowska        $data = $helper->getData($event->data['id'], null, $rev);
1083851b2fbSAnna Dabrowska
1093851b2fbSAnna Dabrowska        if (!$data) return;
1103851b2fbSAnna Dabrowska
1113851b2fbSAnna Dabrowska        foreach ($data as $schema => $fields) {
1123851b2fbSAnna Dabrowska            foreach ($fields as $field => $value) {
1133851b2fbSAnna Dabrowska                $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field);
1143851b2fbSAnna Dabrowska                $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value;
1153851b2fbSAnna Dabrowska            }
1163851b2fbSAnna Dabrowska        }
1173851b2fbSAnna Dabrowska    }
1183851b2fbSAnna Dabrowska
1193851b2fbSAnna Dabrowska    /**
1203851b2fbSAnna Dabrowska     * Remove struct placeholders still present after replacement.
1213851b2fbSAnna Dabrowska     * Requested data was not found.
1223851b2fbSAnna Dabrowska     *
1233851b2fbSAnna Dabrowska     * @param Doku_Event $event
1243851b2fbSAnna Dabrowska     * @param $param
1253851b2fbSAnna Dabrowska     */
126748e747fSAnna Dabrowska    public function cleanupDw2pdf(Doku_Event $event, $param)
1273851b2fbSAnna Dabrowska    {
1283851b2fbSAnna Dabrowska        $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~';
1293851b2fbSAnna Dabrowska        $event->data['content'] = preg_replace($pattern, '', $event->data['content']);
1303851b2fbSAnna Dabrowska    }
13182c064c1SAndreas Gohr}
13282c064c1SAndreas Gohr
13382c064c1SAndreas Gohr// vim:ts=4:sw=4:et:
134