xref: /plugin/struct/action/output.php (revision 5e29103a15bd9873f422f66a6a5239b6aec4651e)
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
107234bfb1Ssplitbrainuse dokuwiki\Extension\ActionPlugin;
117234bfb1Ssplitbrainuse dokuwiki\Extension\Event;
127fe2cdf2SAndreas Gohruse dokuwiki\Extension\EventHandler;
1323f770edSAnna Dabrowskause dokuwiki\plugin\struct\meta\Schema;
1423f770edSAnna Dabrowska
1582c064c1SAndreas Gohr/**
1682c064c1SAndreas Gohr * Class action_plugin_struct_output
1782c064c1SAndreas Gohr *
1882c064c1SAndreas Gohr * This action component handles the automatic output of all schema data that has been assigned
1982c064c1SAndreas Gohr * to the current page by appending the appropriate instruction to the handler calls.
2082c064c1SAndreas Gohr *
2182c064c1SAndreas Gohr * The real output creation is done within the syntax component
2282c064c1SAndreas Gohr * @see syntax_plugin_struct_output
2382c064c1SAndreas Gohr */
247234bfb1Ssplitbrainclass action_plugin_struct_output extends ActionPlugin
25d6d97f60SAnna Dabrowska{
2617a3a578SAndreas Gohr    protected const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT';
273851b2fbSAnna Dabrowska
2882c064c1SAndreas Gohr    /**
2982c064c1SAndreas Gohr     * Registers a callback function for a given event
3082c064c1SAndreas Gohr     *
31*5e29103aSannda     * @param EventHandler $controller DokuWiki's event controller object
3282c064c1SAndreas Gohr     * @return void
3382c064c1SAndreas Gohr     */
347234bfb1Ssplitbrain    public function register(EventHandler $controller)
35d6d97f60SAnna Dabrowska    {
36748e747fSAnna Dabrowska        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handleOutput');
37748e747fSAnna Dabrowska        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replaceDw2pdf');
38748e747fSAnna Dabrowska        $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanupDw2pdf');
3982c064c1SAndreas Gohr    }
4082c064c1SAndreas Gohr
4182c064c1SAndreas Gohr    /**
4282c064c1SAndreas Gohr     * Appends the instruction to render our syntax output component to each page
4328b818ceSAndreas Gohr     * after the first found headline or the very begining if no headline was found
4482c064c1SAndreas Gohr     *
45*5e29103aSannda     * @param Event $event
4682c064c1SAndreas Gohr     * @param $param
4782c064c1SAndreas Gohr     */
487234bfb1Ssplitbrain    public function handleOutput(Event $event, $param)
49d6d97f60SAnna Dabrowska    {
500e4a3e7cSMichael Große        global $ID;
517fe2cdf2SAndreas Gohr        if (!$ID) return;
5202481400SAndreas Gohr        if (!page_exists($ID)) return;
53e6a2e26bSAnna Dabrowska
54c2ad3895SAnna Dabrowska        $pos = 0;
558a30dd7dSFrieder Schrempf        $ins = -1;
568a30dd7dSFrieder Schrempf
57e6a2e26bSAnna Dabrowska        // display struct data at the bottom?
58e6a2e26bSAnna Dabrowska        if ($this->getConf('bottomoutput')) {
59c2ad3895SAnna Dabrowska            $ins = count($event->data->calls);
608a30dd7dSFrieder Schrempf        } elseif (!$this->getConf('topoutput')) {
6128b818ceSAndreas Gohr            foreach ($event->data->calls as $num => $call) {
6228b818ceSAndreas Gohr                // try to find the first header
6328b818ceSAndreas Gohr                if ($call[0] == 'header') {
6428b818ceSAndreas Gohr                    $pos = $call[2];
6528b818ceSAndreas Gohr                    $ins = $num;
6628b818ceSAndreas Gohr                    break;
6728b818ceSAndreas Gohr                }
6882c064c1SAndreas Gohr
6928b818ceSAndreas Gohr                // abort when after we looked at the first 150 bytes
709007da58SMichael Große                if (isset($call[3]) && $call[3] > 150) {
7128b818ceSAndreas Gohr                    break;
7228b818ceSAndreas Gohr                }
7328b818ceSAndreas Gohr            }
74c2ad3895SAnna Dabrowska        }
7528b818ceSAndreas Gohr
7628b818ceSAndreas Gohr        // insert our own call after the found position
7728b818ceSAndreas Gohr        array_splice(
7828b818ceSAndreas Gohr            $event->data->calls,
7928b818ceSAndreas Gohr            $ins + 1,
8028b818ceSAndreas Gohr            0,
817fe2cdf2SAndreas Gohr            [
827fe2cdf2SAndreas Gohr                [
837fe2cdf2SAndreas Gohr                    'plugin',
847fe2cdf2SAndreas Gohr                    [
857fe2cdf2SAndreas Gohr                        'struct_output', ['pos' => $pos], DOKU_LEXER_SPECIAL, ''
867fe2cdf2SAndreas Gohr                    ],
877fe2cdf2SAndreas Gohr                    $pos
887fe2cdf2SAndreas Gohr                ]
897fe2cdf2SAndreas Gohr            ]
9082c064c1SAndreas Gohr        );
9182c064c1SAndreas Gohr    }
9282c064c1SAndreas Gohr
933851b2fbSAnna Dabrowska    /**
943851b2fbSAnna Dabrowska     * If the page has a schema assigned, add its struct data
953851b2fbSAnna Dabrowska     * to dw2pdf's template replacements
963851b2fbSAnna Dabrowska     *
97*5e29103aSannda     * @param Event $event
983851b2fbSAnna Dabrowska     * @param $param
993851b2fbSAnna Dabrowska     */
1007234bfb1Ssplitbrain    public function replaceDw2pdf(Event $event, $param)
1013851b2fbSAnna Dabrowska    {
1023851b2fbSAnna Dabrowska        if (!$event->data['id'] || !page_exists($event->data['id'])) return;
1033851b2fbSAnna Dabrowska
104d4897163SAnna Dabrowska        global $REV;
105d4897163SAnna Dabrowska        $rev = $REV ?: time();
106d4897163SAnna Dabrowska
1073851b2fbSAnna Dabrowska        /** @var helper_plugin_struct $helper */
1083851b2fbSAnna Dabrowska        $helper = plugin_load('helper', 'struct');
109d4897163SAnna Dabrowska        $data = $helper->getData($event->data['id'], null, $rev);
1103851b2fbSAnna Dabrowska
1113851b2fbSAnna Dabrowska        if (!$data) return;
1123851b2fbSAnna Dabrowska
1133851b2fbSAnna Dabrowska        foreach ($data as $schema => $fields) {
11423f770edSAnna Dabrowska            $schemaObject = new Schema($schema);
1153851b2fbSAnna Dabrowska            foreach ($fields as $field => $value) {
11623f770edSAnna Dabrowska                // format fields
11723f770edSAnna Dabrowska                $col = $schemaObject->findColumn($field);
11823f770edSAnna Dabrowska                if (is_a($col->getType(), '\dokuwiki\plugin\struct\types\Date')) {
11923f770edSAnna Dabrowska                    $format = $col->getType()->getConfig()['format'];
12023f770edSAnna Dabrowska                    $value = date($format, strtotime($value));
12123f770edSAnna Dabrowska                }
12223f770edSAnna Dabrowska
1233851b2fbSAnna Dabrowska                $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field);
1243851b2fbSAnna Dabrowska                $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value;
1253851b2fbSAnna Dabrowska            }
1263851b2fbSAnna Dabrowska        }
1273851b2fbSAnna Dabrowska    }
1283851b2fbSAnna Dabrowska
1293851b2fbSAnna Dabrowska    /**
1303851b2fbSAnna Dabrowska     * Remove struct placeholders still present after replacement.
1313851b2fbSAnna Dabrowska     * Requested data was not found.
1323851b2fbSAnna Dabrowska     *
133*5e29103aSannda     * @param Event $event
1343851b2fbSAnna Dabrowska     * @param $param
1353851b2fbSAnna Dabrowska     */
1367234bfb1Ssplitbrain    public function cleanupDw2pdf(Event $event, $param)
1373851b2fbSAnna Dabrowska    {
1383851b2fbSAnna Dabrowska        $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~';
1393851b2fbSAnna Dabrowska        $event->data['content'] = preg_replace($pattern, '', $event->data['content']);
1403851b2fbSAnna Dabrowska    }
14182c064c1SAndreas Gohr}
14282c064c1SAndreas Gohr
14382c064c1SAndreas Gohr// vim:ts=4:sw=4:et:
144