xref: /plugin/struct/syntax/output.php (revision 4cd5cc28e2bf004aed676e9b1f46cc188a4b2240)
1257dd7f8SAndreas Gohr<?php
2d6d97f60SAnna Dabrowska
3257dd7f8SAndreas Gohr/**
4257dd7f8SAndreas Gohr * DokuWiki Plugin struct (Syntax Component)
5257dd7f8SAndreas Gohr *
6257dd7f8SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7257dd7f8SAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8257dd7f8SAndreas Gohr */
9257dd7f8SAndreas Gohr
10f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable;
11ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments;
127cbcfbdbSAndreas Gohruse dokuwiki\plugin\struct\meta\StructException;
13257dd7f8SAndreas Gohr
14d6d97f60SAnna Dabrowskaclass syntax_plugin_struct_output extends DokuWiki_Syntax_Plugin
15d6d97f60SAnna Dabrowska{
1687050b53SMichael Grosse
1787050b53SMichael Grosse    protected $hasBeenRendered = false;
1887050b53SMichael Grosse
197938ca48SAndreas Gohr    const XHTML_OPEN = '<div id="plugin__struct_output">';
207938ca48SAndreas Gohr    const XHTML_CLOSE = '</div>';
217938ca48SAndreas Gohr
22257dd7f8SAndreas Gohr    /**
23bdefb930SAnna Dabrowska     * Class names of renderers which should NOT render struct data.
24bdefb930SAnna Dabrowska     * All descendants are also blacklisted.
25bdefb930SAnna Dabrowska     */
26bdefb930SAnna Dabrowska    const BLACKLIST_RENDERER = array('Doku_Renderer_metadata');
27bdefb930SAnna Dabrowska
28bdefb930SAnna Dabrowska    /**
29979b16f8SAndreas Gohr     * Regexp to check on which actions the struct data may be rendered
30979b16f8SAndreas Gohr     */
31979b16f8SAndreas Gohr    const WHITELIST_ACTIONS = '/^(show|export_.*)$/';
32979b16f8SAndreas Gohr
33979b16f8SAndreas Gohr    /**
34257dd7f8SAndreas Gohr     * @return string Syntax mode type
35257dd7f8SAndreas Gohr     */
36d6d97f60SAnna Dabrowska    public function getType()
37d6d97f60SAnna Dabrowska    {
38257dd7f8SAndreas Gohr        return 'substition';
39257dd7f8SAndreas Gohr    }
40da30fdd3SAndreas Gohr
41257dd7f8SAndreas Gohr    /**
42257dd7f8SAndreas Gohr     * @return string Paragraph type
43257dd7f8SAndreas Gohr     */
44d6d97f60SAnna Dabrowska    public function getPType()
45d6d97f60SAnna Dabrowska    {
46257dd7f8SAndreas Gohr        return 'block';
47257dd7f8SAndreas Gohr    }
48da30fdd3SAndreas Gohr
49257dd7f8SAndreas Gohr    /**
50257dd7f8SAndreas Gohr     * @return int Sort order - Low numbers go before high numbers
51257dd7f8SAndreas Gohr     */
52d6d97f60SAnna Dabrowska    public function getSort()
53d6d97f60SAnna Dabrowska    {
54257dd7f8SAndreas Gohr        return 155;
55257dd7f8SAndreas Gohr    }
56257dd7f8SAndreas Gohr
57257dd7f8SAndreas Gohr    /**
58257dd7f8SAndreas Gohr     * Connect lookup pattern to lexer.
59257dd7f8SAndreas Gohr     *
6082c064c1SAndreas Gohr     * We do not connect any pattern here, because the call to this plugin is not
6182c064c1SAndreas Gohr     * triggered from syntax but our action component
6282c064c1SAndreas Gohr     *
6382c064c1SAndreas Gohr     * @asee action_plugin_struct_output
64257dd7f8SAndreas Gohr     * @param string $mode Parser mode
65257dd7f8SAndreas Gohr     */
66d6d97f60SAnna Dabrowska    public function connectTo($mode)
67d6d97f60SAnna Dabrowska    {
68257dd7f8SAndreas Gohr    }
69257dd7f8SAndreas Gohr
70257dd7f8SAndreas Gohr    /**
71257dd7f8SAndreas Gohr     * Handle matches of the struct syntax
72257dd7f8SAndreas Gohr     *
73257dd7f8SAndreas Gohr     * @param string $match The match of the syntax
74257dd7f8SAndreas Gohr     * @param int $state The state of the handler
75257dd7f8SAndreas Gohr     * @param int $pos The position in the document
76257dd7f8SAndreas Gohr     * @param Doku_Handler $handler The handler
77257dd7f8SAndreas Gohr     * @return array Data for the renderer
78257dd7f8SAndreas Gohr     */
79d6d97f60SAnna Dabrowska    public function handle($match, $state, $pos, Doku_Handler $handler)
80d6d97f60SAnna Dabrowska    {
8182c064c1SAndreas Gohr        // this is never called
8282c064c1SAndreas Gohr        return array();
83257dd7f8SAndreas Gohr    }
84257dd7f8SAndreas Gohr
85257dd7f8SAndreas Gohr    /**
8682c064c1SAndreas Gohr     * Render schema data
87257dd7f8SAndreas Gohr     *
88564e138bSAnna Dabrowska     * Currently completely renderer agnostic
8982c064c1SAndreas Gohr     *
9082c064c1SAndreas Gohr     * @param string $mode Renderer mode
91257dd7f8SAndreas Gohr     * @param Doku_Renderer $R The renderer
92257dd7f8SAndreas Gohr     * @param array $data The data from the handler() function
93257dd7f8SAndreas Gohr     * @return bool If rendering was successful.
94257dd7f8SAndreas Gohr     */
95d6d97f60SAnna Dabrowska    public function render($mode, Doku_Renderer $R, $data)
96d6d97f60SAnna Dabrowska    {
970e4a3e7cSMichael Große        global $ACT;
98257dd7f8SAndreas Gohr        global $ID;
9982c064c1SAndreas Gohr        global $INFO;
100257dd7f8SAndreas Gohr        global $REV;
101bdefb930SAnna Dabrowska
102bdefb930SAnna Dabrowska        foreach (self::BLACKLIST_RENDERER as $blacklisted) {
103bdefb930SAnna Dabrowska            if ($R instanceof $blacklisted) {
1040e4a3e7cSMichael Große                return true;
1050e4a3e7cSMichael Große            }
106bdefb930SAnna Dabrowska        }
10782c064c1SAndreas Gohr        if ($ID != $INFO['id']) return true;
1082f1a213bSAndreas Gohr        if (!$INFO['exists']) return true;
10987050b53SMichael Grosse        if ($this->hasBeenRendered) return true;
110979b16f8SAndreas Gohr        if (!preg_match(self::WHITELIST_ACTIONS, act_clean($ACT))) return true;
11187050b53SMichael Grosse
11287050b53SMichael Grosse        // do not render the output twice on the same page, e.g. when another page has been included
11387050b53SMichael Grosse        $this->hasBeenRendered = true;
1147cbcfbdbSAndreas Gohr        try {
115025cb9daSAndreas Gohr            $assignments = Assignments::getInstance();
1167cbcfbdbSAndreas Gohr        } catch (StructException $e) {
1177cbcfbdbSAndreas Gohr            return false;
1187cbcfbdbSAndreas Gohr        }
119257dd7f8SAndreas Gohr        $tables = $assignments->getPageAssignments($ID);
120257dd7f8SAndreas Gohr        if (!$tables) return true;
121257dd7f8SAndreas Gohr
12267b5dd6eSAnna Dabrowska        if ($mode == 'xhtml') $R->doc .= self::XHTML_OPEN;
1235a1eab78SAndreas Gohr
1247938ca48SAndreas Gohr        $hasdata = false;
125257dd7f8SAndreas Gohr        foreach ($tables as $table) {
126a28d6152SAndreas Gohr            try {
127*4cd5cc28SAnna Dabrowska                $schemadata = AccessTable::getPageAccess($table, $ID, (int)$REV);
128a28d6152SAndreas Gohr            } catch (StructException $ignored) {
129a28d6152SAndreas Gohr                continue; // no such schema at this revision
130a28d6152SAndreas Gohr            }
1310dd23cefSAndreas Gohr            $schemadata->optionSkipEmpty(true);
1320dd23cefSAndreas Gohr            $data = $schemadata->getData();
133da30fdd3SAndreas Gohr            if (!count($data)) continue;
1347938ca48SAndreas Gohr            $hasdata = true;
135257dd7f8SAndreas Gohr
136da30fdd3SAndreas Gohr            $R->table_open();
137da30fdd3SAndreas Gohr
138da30fdd3SAndreas Gohr            $R->tablethead_open();
139da30fdd3SAndreas Gohr            $R->tablerow_open();
140da30fdd3SAndreas Gohr            $R->tableheader_open(2);
141127d6bacSMichael Große            $R->cdata($schemadata->getSchema()->getTranslatedLabel());
142da30fdd3SAndreas Gohr            $R->tableheader_close();
143da30fdd3SAndreas Gohr            $R->tablerow_close();
144ab7b42a5SAnika Henke            $R->tablethead_close();
145da30fdd3SAndreas Gohr
146da30fdd3SAndreas Gohr            $R->tabletbody_open();
147257dd7f8SAndreas Gohr            foreach ($data as $field) {
148257dd7f8SAndreas Gohr                $R->tablerow_open();
149257dd7f8SAndreas Gohr                $R->tableheader_open();
1509e9bee91SAndreas Gohr                $R->cdata($field->getColumn()->getTranslatedLabel());
151257dd7f8SAndreas Gohr                $R->tableheader_close();
152257dd7f8SAndreas Gohr                $R->tablecell_open();
15325852712SAndreas Gohr                if ($mode == 'xhtml') {
154748e747fSAnna Dabrowska                    $R->doc = substr($R->doc, 0, -1) .
155748e747fSAnna Dabrowska                        ' data-struct="' . hsc($field->getColumn()->getFullQualifiedLabel()) .
156748e747fSAnna Dabrowska                        '">';
15725852712SAndreas Gohr                }
158257dd7f8SAndreas Gohr                $field->render($R, $mode);
159257dd7f8SAndreas Gohr                $R->tablecell_close();
160257dd7f8SAndreas Gohr                $R->tablerow_close();
161257dd7f8SAndreas Gohr            }
162257dd7f8SAndreas Gohr            $R->tabletbody_close();
163257dd7f8SAndreas Gohr            $R->table_close();
164da30fdd3SAndreas Gohr        }
165257dd7f8SAndreas Gohr
16667b5dd6eSAnna Dabrowska        if ($mode == 'xhtml') $R->doc .= self::XHTML_CLOSE;
1677938ca48SAndreas Gohr
1687938ca48SAndreas Gohr        // if no data has been output, remove empty wrapper again
16967b5dd6eSAnna Dabrowska        if ($mode == 'xhtml' && !$hasdata) {
1707938ca48SAndreas Gohr            $R->doc = substr($R->doc, 0, -1 * strlen(self::XHTML_OPEN . self::XHTML_CLOSE));
1717938ca48SAndreas Gohr        }
1725a1eab78SAndreas Gohr
173257dd7f8SAndreas Gohr        return true;
174257dd7f8SAndreas Gohr    }
175257dd7f8SAndreas Gohr}
176257dd7f8SAndreas Gohr
177257dd7f8SAndreas Gohr// vim:ts=4:sw=4:et:
178